我已经做了一个功课来做一个按升序排序数组的程序。我这样做了:
#include <stdio.h>
int main()
{
int a[100],i,n,j,temp;
printf("Enter the number of elements: ");
scanf("%d",&n);
for(i=0;i<n;++i)
{
printf("%d. Enter element: ",i+1);
scanf("%d",&a[i]);
}
for(j=0;j<n;++j)
for(i=j+1;i<n;++i)
{
if(a[j]>a[i])
{
temp=a[j];
a[j]=a[i];
a[i]=temp;
}
}
printf("Ascending order: ");
for(i=0;i<n;++i)
printf("%d ",a[i]);
return 0;
}
输入不会超过10个数字。这可以用比我在这里做的少量代码完成吗?我希望代码尽可能地最短。任何帮助都将受到赞赏。谢谢!
答案 0 :(得分:4)
你有10行进行排序。 如果你被允许使用别人的工作(后续注释表明你不能这样做),你可以通过编写比较器函数并调用标准C库qsort()
来减少这种情况。功能:
static int compare_int(void const *v1, void const *v2)
{
int i1 = *(int *)v1;
int i2 = *(int *)v2;
if (i1 < i2)
return -1;
else if (i1 > i2)
return +1;
else
return 0;
}
然后电话是:
qsort(a, n, sizeof(a[0]), compare_int);
现在,我按照我做的方式写了这个函数。特别是,它避免了算术溢出,写这不是:
static int compare_int(void const *v1, void const *v2)
{
return *(int *)v1 - *(int *)v2;
}
此外,原始模式概括为比较结构等。您比较第一个字段的不等式返回适当的结果;如果第一个字段不相等,那么你比较第二个字段;然后是第三个,然后是N th ,只有在每个比较显示值相等时才返回0。
显然,如果您应该编写排序算法,那么除了调用qsort()
之外,您还需要做更多的工作。您的算法是冒泡排序。它是最低效的分选技术之一 - 它是O(N 2 )。你可以查找插入排序(也是O(N 2 ))但比冒泡排序更有效,或者选择排序(也是二次),或者Shell排序(非常大致为O(N 3) / 2 )),或堆排序(O(NlgN)),或快速排序(平均为O(NlgN),但在最坏的情况下为O(N 2 ),或简介排序。唯一可能比你写的更短的是插入和选择排序;对于大量数据,其他的将更长但更快。对于像10或100这样的小集合,效率并不重要 - 所有种类都可以。但是当你进入1,000或1,000,000个条目时,排序算法确实很重要。关于不同的排序算法,您可以在Stack Overflow上找到很多问题。您可以在维基百科中轻松找到所提及的任何和所有算法的信息。
顺便提一下,如果输入的数量不超过10个,则不需要大小为100的数组。
答案 1 :(得分:2)
如果你知道数组元素的范围,一种方法是使用另一个数组来存储每个数组元素的频率(所有元素应该是int
:))并打印排序的数组。我发布了大量元素(10
6
)。您可以根据需要减少它:
#include <stdio.h>
#include <malloc.h>
int main()
{
int t, num, *freq = malloc(sizeof(int)*1000001);
for(int i = 0; i < 1000001; i++)
freq[i] = 0;
scanf("%d",&t);
for(int i = 0; i < t; i++)
{
scanf("%d", &num);
freq[num]++;
}
for(int i = 0; i < 1000001; i++)
if(freq[i])
while(freq[i]--)
printf("%d\n", i);
}
可以进一步修改此算法。修改后的版本称为计数排序,它会在 Θ(n) 时间内对数组进行排序。
计数排序假定每个
n
输入元素都是该范围内的整数0 to k
,对于某个整数k
。当 k = O(n)时,排序会在Θ(n)
时间内运行。 对于每个输入元素x
,计数排序确定较少的元素数 比x
。它使用此信息将元素x
直接放入其中的位置 输出数组。例如,如果17个元素小于x
,则x
属于输出 我们必须稍微修改这个方案以处理其中的情况 几个元素具有相同的值,因为我们不想将它们全部放入 同样的立场。在计算排序的代码中,我们假设输入是一个数组
A[1...n]
和 因此 A.length = n 。我们需要另外两个数组:数组B[1....n]
包含数组 排序输出,数组C[0....k]
提供临时工作存储。
这个算法的伪代码:
for i ← 1 to k do
c[i] ← 0
for j ← 1 to n do
c[A[j]] ← c[A[j]] + 1
//c[i] now contains the number of elements equal to i
for i ← 2 to k do
c[i] ← c[i] + c[i-1]
// c[i] now contains the number of elements ≤ i
for j ← n downto 1 do
B[c[A[i]]] ← A[j]
c[A[i]] ← c[A[j]] - 1
<子> 1。内容取自Introduction to Algorithms Thomas H. Cormen等人。