以下是用于按非递减顺序对数字进行排序的代码:
#include<stdio.h>
#include<stdlib.h>
# define size 1000001
static int a[size];
int main()
{
int t, k, i;
scanf("%d", &t);
for(i = 0; i < t; i++)
{
scanf("%d", &k);
a[k] += 1;
}
for(i = 0; i < 1000001; i++)
{
while(a[i]-- != 0)
printf("%d\n", i);
}
return 0;
}
如果有人能够向我解释代码,那将是非常有帮助的。我已经完成了代码,我不知道如何对数字进行排序。在任何地方都没有进行交换,但它仍然适用于c ++编辑器。
答案 0 :(得分:2)
这个程序不会在数学意义上对数字进行排序,但这并不重要,因为它会给你一种幻觉。
该程序要求t
,这将更好地命名为numberOfValues
...您将输入的值的数量。
数组a[size]
可以被认为是size
值桶。在您的程序中,这些buckets
只是计数器。每个桶都有一个0到0的数字。输入值5
后,存储区a[5]
的计数会增加。这一直持续到所有存储桶都设置完毕。
程序然后通过桶工作。大部分存储桶都是空的,但当存储桶非零时(while a[i] != 0
- 暂时忽略丢失的--
),存储桶需要同时“清空”,其内容需要加以考虑。存储桶a[i]
包含i
个元素的计数,因此循环打印出排序中下一个值为i
的值,同时还会减少计数(a[i]--
)。这一直持续到存储桶为空(== 0
)并且程序移动到下一个存储桶。
最终所有的存储桶都已清空,排序已完成。
答案 1 :(得分:1)
代码不错,但空间复杂度高。
这部分代码
for(i = 0; i < t; i++)
{
scanf("%d", &k);
a[k] += 1;
}
存储输入数字的频率(有点像散列)
如果我输入了 5 4 2 4 2
然后
a[5] =1
a[4] =2
a[2] =2
其他都为零
所以如果你想在数组中找到“n”的频率,那么只需打印 a[n]
现在来回答你的问题
此代码如何对数字进行排序?
while(a[i]--!=0)
有什么用?
回答第一个问题:
我们从 0 到 1000001 在奥德所以如果输入 4 2 5 6
当循环从 0 到 100001 时,它首先检查 a[2] !=0 然后 a[4] 然后 a[5] 然后 a[6] 打印所有非零频率项。
因此根据检查 oder first 2 4 5 6 被打印
回答第二个问题:
为什么不是 while(a[i]!=0)
因为我只检查它是否非零,如果它的非零允许打印数字
但是说我输入了 4 3 2 4 2
然后输出应该打印 2 2 3 4 4
所以使用 while(a[i] --!=0)
它打印数字 a[i] 次说如果
a[4]=2 这意味着 4 出现了 2 次因此它应该打印 4 4 所以 while 循环作为 a[4] =2 运行两次
答案 2 :(得分:0)
每次打印时将变量a[i]
递减到0为止
答案 3 :(得分:0)
没有交换因为不需要:数字不像往常一样存储,它使用一个巨大的数组来标记输入的数字:
如果添加数字200,则存储数组[200] = 1。如果再次添加200,则array [200] = 2。
然后,它按以下方式打印数组:想象你有[0,1,2,1,0,0 ...],所以有一个1,2两个,一个3 ... 所以它只显示1,2,2,3
答案 4 :(得分:0)
代码迭代数组a
中的每个值。数组中的每个值a[i]
都在while循环中迭代。 while(a[i]--!=0)
检查a [i]的值是否为零。如果不是,则执行循环体。当控件进入循环体时,减小a [i]值。例如)如果a [i] = 6,则输出为:
5
4
3
2
1
0
答案 5 :(得分:0)
考虑i = 0;
然后a[i]--!=0
将被执行,直到a[i]
的值不会变为zero
。当a[i]
的值变为zero
时,循环将终止并且下一次迭代{ {1}}循环将开始。