这是C(选择排序)中的简单代码:
#include <stdio.h>
#include <stdlib.h>
#define ItemCount 10
int numbers[ItemCount] = {4,9,3,7,2,5,10,2,12,6};
int MinNumberIndex(int start) {
int i;
int minindex = start;
for (i = start + 1; i < ItemCount; i++)
if (numbers[minindex] > numbers[i])
minindex = i;
return minindex;
}
void SelectionSort() {
int i,temp,minindex;
for (i = 0; i < 10; i++) {
minindex = MinNumberIndex(i);
temp = numbers[i];
numbers[i] = numbers[minindex ];
numbers[minindex ] = temp;
}
}
int main() {
int i;
SelectionSort();
for (i = 0; i < 10; i++)
printf("%d\t", numbers[i]);
system("pause");
}
它工作正常......但如果我改变一点(在selectionSort函数中):
for (i = 0; i < 10; i++) {
temp = numbers[i];
numbers[i] = numbers[MinNumberIndex(i)];
numbers[MinNumberIndex(i)] = temp;
}
它不起作用......为什么?它似乎是一样的。
答案 0 :(得分:2)
MinNumberIndex返回的值取决于数组的内容。您执行以下操作时更改内容:
numbers[i] = numbers[MinNumberIndex(i)];
所以接下来的电话:
numbers[MinNumberIndex(i)] = temp;
将/可以存储到错误的单元格,因为MinNumberIndex(i)可以更改。这会破坏算法,因为您没有进行适当的交换。
答案 1 :(得分:1)
因为MinNumberIndex(i)
每次调用它都会返回不同的值,所以第二个版本实际上不是值交换。
答案 2 :(得分:1)
由于MinNumberIndex(i)
返回范围[i,ItemCount-1]
中最小元素的索引,而您的备用代码版本会在两次调用MinNumberIndex()
之间修改数组中的范围,不要交换元素。
您的备用循环与以下内容相同:
for (i=0;i<10;i++)
{
temp = numbers[i];
numbers[i] = numbers[MinNumberIndex(i)];
numbers[i] = temp;
}
更详细一点,当这行代码在for
循环中执行时:
numbers[i] = numbers[MinNumberIndex(i)];
这使numbers[i]
成为您当时正在处理的数组范围中的最小值,因此下次调用MinNumberIndex(i)
时,它将返回i
。并且
numbers[i] = temp;
只会将数组恢复到循环顶部的状态。