为什么我的 SelectionSort 并不总是有效?
Why does my SelectionSort not always work?
我是初学者,现在我正在尝试第二天实施 SelectionSort 以进行练习。
我使用的算法大部分时间都有效,但并非总是有效。不幸的是,我完全不清楚为什么它并不总是有效。
这个例子是一个不起作用的例子。
#include <stdio.h>
int* selectionSort(int a_count, int *a);
int main(void)
{
int a[] = {4,2,3,4,4,9,98,98,3,3,3,4,2,98,1,98,98,1,1,4,98,2,98,3,9,9,3,1,4,1,98,9,9,2,9,4,2,2,9,98,4,98,1,3,4,9,1,98,98,4,2,3,98,98,1,99,9,98,98,3,98,98,4,98,2,98,4,2,1,1,9,2,4};
int i, a_count = 73;
int *result = selectionSort(a_count, a);
for(i = 0; i < a_count; i++){
printf("%i ", result[i]);
}
return 0;
}
int* selectionSort(int a_count, int* a) {
int i, j, min = 0, tmp;
for(i = 0; i < a_count - 1; i++){
min = i;
printf("min_i = %i\n", min);
for(j = i + 1; j < a_count; j++){
printf("j = %i ", j);
if(a[j] < a[min]){
printf("%i < %i\n", a[j], a[min]);
printf("min is changed: ");
min = j;
printf("min_j = %i\n", min);
}
tmp = a[i];
a[i] = a[min];
a[min] = tmp;
}
}
return a;
}
非常感谢您的帮助!
您在 j
循环的每次迭代中将元素 i
与元素 min
交换。这既不正确又低效。在内部循环完成后执行交换,以便 min
实际上包含当前子数组的最小值的索引,而不是在您仍在尝试找出该元素的位置时。
有一个简单的错误,就是你没有等到内循环结束才进行交换。
int* selectionSort(int a_count, int* a) {
int i, j, min = 0, tmp;
for(i = 0; i < a_count - 1; i++){
min = i;
printf("min_i = %i\n", min);
for(j = i + 1; j < a_count; j++){
printf("j = %i ", j);
if(a[j] < a[min]){
printf("%i < %i\n", a[j], a[min]);
printf("min is changed: ");
min = j;
printf("min_j = %i\n", min);
}
}
tmp = a[i]; // three lines moved out of the loop
a[i] = a[min]; //
a[min] = tmp; //
}
return a;
}
现在输出正确了。
你有两个循环,在外层循环中,你先设置了min,然后在内层循环中,min改变了,这弄乱了min值,使你的交换代码错误。
您可以删除所有关于 min 的代码,直接使用 i, j,然后应该可以工作。
改变
如果(a[j] < a[min])
到
如果(a[j] < a[i])
public static class SelectionSort
{
static int min;
public static void Sort(int[] data)
{
for (int i = 0; i < data.Length; i++)
{
for (int j = 0; j < data.Length; j++)
{
min = j;
if (data[i] < data[j])
Swap(x: ref data[i], y: ref data[min]);
}
}
}
private static void Swap(ref int x, ref int y)
{
int temp = x;
x = y;
y = temp;
}
}
我是初学者,现在我正在尝试第二天实施 SelectionSort 以进行练习。 我使用的算法大部分时间都有效,但并非总是有效。不幸的是,我完全不清楚为什么它并不总是有效。 这个例子是一个不起作用的例子。
#include <stdio.h>
int* selectionSort(int a_count, int *a);
int main(void)
{
int a[] = {4,2,3,4,4,9,98,98,3,3,3,4,2,98,1,98,98,1,1,4,98,2,98,3,9,9,3,1,4,1,98,9,9,2,9,4,2,2,9,98,4,98,1,3,4,9,1,98,98,4,2,3,98,98,1,99,9,98,98,3,98,98,4,98,2,98,4,2,1,1,9,2,4};
int i, a_count = 73;
int *result = selectionSort(a_count, a);
for(i = 0; i < a_count; i++){
printf("%i ", result[i]);
}
return 0;
}
int* selectionSort(int a_count, int* a) {
int i, j, min = 0, tmp;
for(i = 0; i < a_count - 1; i++){
min = i;
printf("min_i = %i\n", min);
for(j = i + 1; j < a_count; j++){
printf("j = %i ", j);
if(a[j] < a[min]){
printf("%i < %i\n", a[j], a[min]);
printf("min is changed: ");
min = j;
printf("min_j = %i\n", min);
}
tmp = a[i];
a[i] = a[min];
a[min] = tmp;
}
}
return a;
}
非常感谢您的帮助!
您在 j
循环的每次迭代中将元素 i
与元素 min
交换。这既不正确又低效。在内部循环完成后执行交换,以便 min
实际上包含当前子数组的最小值的索引,而不是在您仍在尝试找出该元素的位置时。
有一个简单的错误,就是你没有等到内循环结束才进行交换。
int* selectionSort(int a_count, int* a) {
int i, j, min = 0, tmp;
for(i = 0; i < a_count - 1; i++){
min = i;
printf("min_i = %i\n", min);
for(j = i + 1; j < a_count; j++){
printf("j = %i ", j);
if(a[j] < a[min]){
printf("%i < %i\n", a[j], a[min]);
printf("min is changed: ");
min = j;
printf("min_j = %i\n", min);
}
}
tmp = a[i]; // three lines moved out of the loop
a[i] = a[min]; //
a[min] = tmp; //
}
return a;
}
现在输出正确了。
你有两个循环,在外层循环中,你先设置了min,然后在内层循环中,min改变了,这弄乱了min值,使你的交换代码错误。 您可以删除所有关于 min 的代码,直接使用 i, j,然后应该可以工作。 改变 如果(a[j] < a[min]) 到 如果(a[j] < a[i])
public static class SelectionSort
{
static int min;
public static void Sort(int[] data)
{
for (int i = 0; i < data.Length; i++)
{
for (int j = 0; j < data.Length; j++)
{
min = j;
if (data[i] < data[j])
Swap(x: ref data[i], y: ref data[min]);
}
}
}
private static void Swap(ref int x, ref int y)
{
int temp = x;
x = y;
y = temp;
}
}