为什么我的插入排序不喜欢重复的整数?

时间:2015-11-30 00:21:30

标签: c insertion-sort

当我使用具有重复项的整数列表提供我的排序代码时,代码无法正常运行。我的猜测是,对于每个重复的整数,列表中小于它的其他整数的数量对于每个重复都是相同的。因此,每个副本的位置在新数组(d[10])中是相同的。这是代码的样子:

#include <stdio.h>

int main(void)
{
  int i, j, k;
  int c[10];
  int d[10];

  printf("enter 10 integers each separated by a space: ");

  for (i = 0; i < 10; i++)
    {
      scanf("%d", &c[i]);
    }

  printf("before insertion: ");
  for (i = 0; i < 10; i++)
    {
      printf("%d ", c[i]);
    }
  printf("\n");

  for (i = 0; i < 10; i++) // sort loop begins here
    {
      k = 0;
      for (j = 0; j < 10; j++)
        {
          if (c[j] < c[i])
            {
              k = k + 1; // count number of times a smaller number is found
            }
        }
      d[k] = c[i]; // use the number k as the position in the new array
    }

  printf("after insertion: ");
  for (i = 0; i < 10; i++)
    {
      printf("%d ", d[i]);
    }
  printf("\n");

  return 0;
}

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

这不是插入排序,你编写的代码具有空间复杂度O(n),就排序技术而言并不好,空间成本在所有情况下的时间复杂度都是O(n ^ 2)这是更糟糕的,所以不要使用这样的排序算法。

您可以搜索google或youtube进行插入排序。

为什么您的代码会产生问题?

答: - 您的代码将所需元素放在k计算的确切位置上。但是如果你输入一些重复的元素,那么会发生一次又一次遇到重复元素的第一个位置,所以你的代码实际上没有为下一个重复元素放置元素,并且在那个地方你得到一个垃圾值。 / p>

如何解决这个问题?

好的,所以你需要改变你的算法,它会考虑所有的位置,你不应该为两个相同的k值放置元素。 有很多方法可以做到这一点,我可以建议你的一种方法是散列(我猜它不是解决这个问题的最佳方法),有时也称为数组指针技术(如果你不知道,你可以浏览这个)你只需要一个大小为n的数组,将其初始化为零,然后你就可以计算array[k]++

所遇到的k次数

希望这可以解决问题。

答案 1 :(得分:1)

这不是插入排序。它类似于循环排序,它最大限度地减少了对d []的写入次数。我使用第三个数组e []添加了一个重复检查,以指示是否已写入位置。代码测试10 ^ 8个案例。通过评论注意到的变化。

int main()
{
int c[10] = {0};                
int d[10];
int e[10];                                      // for duplicate check
int i, j, k, n;

    for(n = 0; n < 100000000; n++){             // test 10^8 cases
        k = n;
        for(i = 0; i < 10; i++){
            c[i] = k%10;
            k /= 10;
        }
        for(i = 0; i < 10; i++){                // clear e (nothing written)
            e[i] = 0;
        }
        for (i = 0; i < 10; i++){
            k = 0;
            for (j = 0; j < 10; j++){
                if (c[j] < c[i]){
                    k = k + 1;
                }
            }
            while(e[k] != 0 && d[k] == c[i]){  // duplicate check
                k = k + 1;
            }
            d[k] = c[i];
            e[k] = 1;                          // mark index as written
        }
        for(i = 0; i < 9; i++){
            if(d[i] > d[i+1]){
                printf("fail\n");
            }
        }
    }
    return(0);
}