C中的插入排序有什么问题?

时间:2014-08-03 19:46:42

标签: c insertion-sort

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <stddef.h>

void insertionSort(int ar_size, int* ar) {
    int i, j;
    int temp = 0;
    for (i = 1; i < ar_size; i++) {
        j = i;
        while (j > 0 && ar[i - 1] > ar[i]) {
            temp = ar[i - 1];
            ar[i - 1] = ar[i];
            ar[i] = temp;
            j--;
        }
    }
    for (j = 0; j < ar_size; j++) {
        printf("%d", ar[j]);
        printf(" ");
    }
}
int main(void) {
    int _ar_size;
    scanf("%d", &_ar_size);
    int _ar[_ar_size], _ar_i;
    for (_ar_i = 0; _ar_i < _ar_size; _ar_i++) {
        scanf("%d", &_ar[_ar_i]);
    }

    insertionSort(_ar_size, _ar);

    return 0;
}

我一直在努力寻找错误。我什么也看不见。这段代码有什么问题?

输入为64 1 3 5 6 2时,输出为1 3 4 5 2 6。循环的迭代次数少一点,但我不明白为什么?请帮忙。感谢。

4 个答案:

答案 0 :(得分:2)

将值推到前面时,您似乎使用了错误的迭代器。

while(j>0 && ar[j-1]>ar[j]) {
  temp = ar[j-1];
  ar[j-1] = ar[j];
  ar[j] = temp;
  j--;
}

答案 1 :(得分:2)

您在函数的内部循环中使用索引i而不是索引j。

    while(j>0 && ar[i-1]>ar[i])
    {
        temp = ar[i-1];
        ar[i-1] = ar[i];
        ar[i] = temp;
        j--;
    }

这里必须使用索引j。

此功能还输出已排序的数组也是一个坏主意。它应该只进行排序。 另一个坏主意是使用以不受欢迎的方式开头的标识符。 当第一个参数是数组而第二个参数是数组的大小时,它会更好。

代码可以采用以下方式

#include <stdio.h>

void InsertionSort( int *a, int n ) 
{    
    int i;

    for ( i = 1; i < n; i++ )
    {
        int j = i;
        while ( j > 0 && a[j-1] > a[j] )
        {
            int tmp = a[j-1];
            a[j-1]  = a[j];
            a[j]    = tmp;
            --j;
        }
    }
}



int main(void) 
{
    int size;
    scanf( "%d", &size );

    int a[size]; 
    int i;

    for ( i = 0; i < size; i++ ) scanf( "%d", &a[i] );

    for ( i = 0; i < size; i++ )
    {
        printf( "%d ", a[i] );
    }       
    puts( "" );

    InsertionSort( a, size );

    for ( i = 0; i < size; i++ )
    {
        printf( "%d ", a[i] );
    }       
    puts( "" );

    return 0;
}

如果输入是

10
 2 7 5 4 9 1 4 8 3 5

然后输出

2 7 5 4 9 1 4 8 3 5 
1 2 3 4 4 5 5 7 8 9 

答案 2 :(得分:0)

尝试在一张纸上进行干运行,很容易发现问题。

for (i = 1; i < ar_size; i++) {
   j = i;
   while (j > 0 && ar[i-1] > ar[i]) {  // problem begins here
      temp = ar[i-1];
      ar[i-1] = ar[i];
      ar[i] = temp;
      j--;
   }
}

i在内循环中没有变化。

在某些时候,您的计划会将62进行互换,您的示例输入列表将变为1 3 4 5 2 6a[i-1]2,而a[i]6由于ar[i-1] > ar[i]条件,程序的流程不会进入内循环。

尝试此修复:

for (i = 1; i < ar_size; i++) {
   j = i;
   while (j > 0 && ar[j-1] > ar[j]) {
      temp = ar[j-1];
      ar[j-1] = ar[j];
      ar[j] = temp;
      j--;
   }
}

答案 3 :(得分:0)

您的插入排序问题是您在以下代码中将j索引替换为i索引:

        while(j>0 && ar[j-1]>ar[j])
        {
            temp = ar[j];
            ar[j] = ar[j-1];
            ar[j-1] = temp;
            j--;
        }

请注意,在请求输入时,最好打印一个描述预期输入的简短语句。 (是的,快速的脏测试是一个例外)它可以更容易避免错误,例如:

    printf ("enter array size: ");
    scanf ("%d", &_ar_size);
    int _ar[_ar_size], _ar_i;
    for (_ar_i = 0; _ar_i < _ar_size; _ar_i++) {
        printf ("enter array element[%d] : ", _ar_i);
        scanf ("%d", &_ar[_ar_i]);
    }