选择排序在C.为什么?

时间:2011-03-05 16:31:35

标签: c sorting selection

这是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;                                                                          
}

它不起作用......为什么?它似乎是一样的。

3 个答案:

答案 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;

只会将数组恢复到循环顶部的状态。