#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/**************************************************************
*计数排序。
*参数: data : 要排序的数组
* size :数组元素的个数
* k :数组中元素数组最大值 +1 (这个需要+1)
*返回值: 成功0;失败-1.
* ************************************************************/
int ctsort(int *data, int size, int k)
{
int * counts = NULL,/*计数数组*/
* temp = NULL;/*保存排序后的数组*/
int i = 0;
/*申请数组空间*/
if ((counts = (int *) malloc( k * sizeof(int))) == NULL)
return -1;
if ((temp = (int *) malloc( k * sizeof(int))) == NULL)
return -1;
/*初始化计数数组*/
for (i = 0; i < k; i ++)
counts[i] = 0;
/*数组中出现的元素,及出现次数记录*/
for(i = 0; i < size; i++)
counts[data[i]] += 1;
/*调整元素计数中,加上前一个数*/
for (i = 1; i < k; i++)
counts[i] += counts[i - 1];
/*使用计数数组中的记录数值,来进行排序,排序后保存的temp*/
for (i = size -1; i >= 0; i --){
temp[counts[data[i]] - 1] = data[i];
counts[data[i]] -= 1;
}
memcpy(data,temp,size * sizeof(int));
free(counts);
free(temp);
return 0;
}
int main()
{
int a[8] = {1,0,2,1,4,5,7,4};
int max = a[0],
i = 0;
/*获得数组中中的数值*/
for ( i = 1; i < 8; i++){
if (a[i] > max)
max = a[i];
}
ctsort(a,8,max+1);
for (i = 0;i < 8;i ++)
printf("%d\n",a[i]);
}
基数排序
基数排序是另外一种高效的线性排序算法。其方法为将数据按位分开,并从数据的最低有效位到最高的有效位进行比较依次排序,从而得到有序的集合。我们来看一个简单的例子:{15,12,49,16,36,40};
在对个位进行排序之后,其结果是{40,12,15,16,36,49};
在对十位进行排序后,其结果是{12,15,16,36,40,49};
有一点很重要就是必须保证在对每个位进行排序时,其排序过程必须是稳定的。也就是说,数据在进行较低位排序之后,此数据的位置不应该改变,除非进行较高位比较时需要对它进行调整。也就是例子中,个为排序后是 12 15 16 在进行十位排序时,十位都是1,这时,不应该对其进行调整。下面直接看代码吧,代码中对个位进行排序时,采用的上面的计数排序的算法,保证了排序过程的稳定性。
/*rxsort.c*/
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/***************************************************************
*用基数排序对十进制数进行排序
*参数: data:数组元素 size:数组中元素的个数
* p:元素中最大的位数; k :基数 (十,八,二,16,进制等等)
*返回值 :成功0,失败-1;
* 函数有运行结束后,已排序好的序列保存在data中
**************************************************************/
int rxsort(int *data, int size, int p, int k)
{
int * counts,/*计数数组*/
* temp;/*临时保存排序后的数组*/
int index,
pval,
i,
j,
n;
/*申请空间*/
if ((counts = (int *)malloc(k * sizeof(int))) == NULL)
return -1;
if ((temp = (int *)malloc(size * sizeof(int))) == NULL)
return -1;
/*从低位到高位分别进行排序*/
for (n = 0; n < p; n++){
/*计数数组初始化*/
for ( i = 0; i < k; i ++)
counts[i] = 0;
/*计算当前位的基数*/
pval = (int) pow((double )k, (double)n);
/*下面的实现参数计数排序部分*/
for (j = 0; j < size; j ++){
index = (data[j]/pval)%pval;
counts[index] += 1;
}
for (i = 1; i < k; i ++)
counts[i] += counts[i - 1];
for(j = size - 1; j >= 0; j --){
index = (data[j]/pval)%pval;
temp[counts[index] - 1] = data[j];
counts[index] -= 1;
}
memcpy(data, temp, size *sizeof(int));
}
free(counts);
free(temp);
return 0;
}
int main()
{
int a[20] = {20,300,40,5,80,12,500,43,23,56,121,33,444,555,666,112,456,234,123,124};
int i = 0;
rxsort(a,20,3,10);
for (i = 0; i< 20; i++)
printf ("a[%d] = %d\n",i,a[i]);
}