计数排序

计数排序假设n个输入元素中的每一个都是在0到k区间内的一个整数,其中k为某个整数。
计数排序的基本思想是:对每一个输入元素x,确定小于x的元素的个数。利用这一信息就可以把x直接放在它的输出
数组中的位置上。
在计数排序中,假设输入是一个数组A[1..n],A.length=n。我们还需要两个数组:B[1..n]存放排序的输出,
C [0..k]提供存储空间。
COUNTING——SORT(A,B,k)
let C[0..k] be a new array
for i=0 to k
	C[i]=0
for j=1 to A.length
	C[A[j]]=C[A[j]]+1           //现在C[i]中的数是元素值等于i 的数目
for i = 1 to k
	C[i]=C[i]+C[i-1]            //现在C[i]是元素值小于等于i的数目
for j=A.length downto 1
	B[C[A[j]]]=A[j]              //从后往前把A数组中的元素放入到输出数组中合适的位置
	C[A[j]]=C[A[j]]-1            //放完该元素后,把保存小于等于该元素的数组对应的值减一
      算法第9行采用了从后往前的形式输出到输出数组,也可以从前开始,但是不能保证稳定性。
下面是一个算法运行的例子:
计数排序_第1张图片 计数排序_第2张图片 计数排序_第3张图片 计数排序_第4张图片 计数排序_第5张图片 计数排序_第6张图片 计数排序_第7张图片 计数排序_第8张图片 计数排序_第9张图片 计数排序_第10张图片 计数排序_第11张图片 计数排序_第12张图片 计数排序_第13张图片 计数排序_第14张图片 计数排序_第15张图片
计数排序的时间代价:地3~4行的for循环所花的时间是,第4,5行所花的时间是,6~7行所花的时间是,这样总的时间代价就是。在实际工作中,当k=O(n)时,一般会采用计数排序,这样的运行时间为
实现代码如下:
#include <stdio.h>
void COUNTINGSORT(int *A, int *B, int array_size, int k)
{
        int C[k+1], i, value, pos;
        for(i=0; i<=k; i++)
        {
            C[i] = 0;
        }
        for(i=0; i< array_size; i++)
        {
            C[A[i]] ++;
        }
        for(i=1; i<=k; i++)
        {
            C[i] = C[i] + C[i-1];
        }
        for(i=array_size-1; i>=0; i--)
        {
            value = A[i];
            pos = C[value];
            B[pos-1] = value;
            C[value]--;
        }
}

 int max(int arr[],int length)
{
 int max=arr[0];
 for (int i=1;i<length;i++) 
  if(max < arr[i]) 
	  max = arr[i];
 return max;
}
int main()
{
        int A[] = {2, 5, 3, 0, 2, 3, 0, 3},  i;
		length=sizeof(A)/sizeof(A[0]);
		/*
		定义数组后可以用sizeof命令获得数组的长度(可容纳元素个数)。例如:

		int data[4];
		int length;
		length=sizeof(data)/sizeof(data[0]);  数组占内存总空间,除以单个元素占内存空间大小
		但是,通过传递数组名参数到子函数中,以获得数组长度是不可行的。例如:

			int getLength(int[] a){
				int length;
				length=sizeof(a)/sizeof(a[0]); 这样是错误的,得到的结果永远是1
				return length;
			}

		因为,a是函数参数,到了本函数中,a只是一个指针(地址,系统在本函数运行时,是不知道a所表示的地址有多大的数据存储空间,
		这里只是告诉函数:一个数据存储空间首地址),所以,sizoef(a)的结果是指针变量a占内存的大小,一般在32位机上是4个字节。
		a[0]是int类型,sizeof(a[0])也是4个字节,所以,结果永远是1。

		因此,获得数组长度,只能在数组定义所在的代码区中,采用以上方法,才可以达到效果。
		
		*/
		int B[length];
		int max=max(A,length);
        COUNTINGSORT(A, B, length, max);
		
        for (i=0; i<= 7; i++)
        {
            printf("%d ", B[i]);
        }
        printf("\n");
        return 0;
}


你可能感兴趣的:(C语言,计数排序,算法+实现)