当我使用具有重复项的整数列表提供我的排序代码时,代码无法正常运行。我的猜测是,对于每个重复的整数,列表中小于它的其他整数的数量对于每个重复都是相同的。因此,每个副本的位置在新数组(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;
}
我该如何解决这个问题?
答案 0 :(得分:2)
这不是插入排序,你编写的代码具有空间复杂度O(n),就排序技术而言并不好,空间成本在所有情况下的时间复杂度都是O(n ^ 2)这是更糟糕的,所以不要使用这样的排序算法。
您可以搜索google或youtube进行插入排序。
答: - 您的代码将所需元素放在k计算的确切位置上。但是如果你输入一些重复的元素,那么会发生一次又一次遇到重复元素的第一个位置,所以你的代码实际上没有为下一个重复元素放置元素,并且在那个地方你得到一个垃圾值。 / p>
好的,所以你需要改变你的算法,它会考虑所有的位置,你不应该为两个相同的k值放置元素。
有很多方法可以做到这一点,我可以建议你的一种方法是散列(我猜它不是解决这个问题的最佳方法),有时也称为数组指针技术(如果你不知道,你可以浏览这个)你只需要一个大小为n的数组,将其初始化为零,然后你就可以计算array[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);
}