对含n个元素的一个输入序列,任何比较排序在最坏情况下都要用
Θ(
n lg
n)次比较来进行排序。下面讨论三种以线性时间运行的算法:计数排序、基数排序和桶排序。这些算法都用了非比较的一些操作来确定元素的次序。
一、计数排序
计数排序假设n个输入元素中的每一个都是介于1到k之间的整数,此处k是整数。当k = O(n) 时,计数排序的运行时间为O(n) 。
计数排序算法的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数。有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。
CountingSortMain.c
#include
<
stdio.h
>
#include
<
stdlib.h
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#define
ARRLEN 9
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
CountingSort(
int
*
a,
int
*
b,
int
arrLen,
int
k);
void
PrintArr(
int
*
arr,
int
arrLen);
int
ArrMaxElem(
int
*
arr,
int
arrLen);
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/*
*n为数组a的长度,k为数组a中最大值。
*c[i]记录a数组中数值大于或等于i的个数
*/
void
CountingSort(
int
*
a,
int
*
b,
int
arrLen,
int
k)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int i;
int *c;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
c = (int *)malloc((k + 1) * sizeof(int));
for(i = 0; i <= k; i++)
c[i] = 0;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//*c[i]包含等于i的元素个数*/
for(i = 0; i < arrLen; i++)
c[a[i]]++;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//*c[i]包含小于等于i的元素个数*/
for(i = 1; i <= k; i++)
c[i] += c[i-1];
for(i = arrLen - 1; i >= 0; i--)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
b[c[a[i]] - 1] = a[i];
c[a[i]]--;
}
free(c);
c = NULL;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
PrintArr(
int
*
arr,
int
arrLen)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int i;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(i = 0; i < arrLen; i++)
printf("%3d ", arr[i]);
printf(" ");
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
ArrMaxElem(
int
*
arr,
int
arrLen)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int i, max;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
max = arr[0];
for(i = 1; i < arrLen; i++)
if(max < arr[i])
max = arr[i];
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return max;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
main(
int
argc,
char
**
argv)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
int a[ARRLEN] = ...{4, 4, 3, 1, 1, 9, 8, 11, 8} ;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
int b[ARRLEN] = ...{0, };
CountingSort(a, b, ARRLEN, ArrMaxElem(a, ARRLEN));
PrintArr(b, ARRLEN);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return 0;
}