基数排序的描述
基数排序是另外一种高效的线性排序算法。其方法是将数据按位分开,并从数据的最低有效位到最高有效位,依次排序,从而得到有序数据集合。例如:用基数排序对十进制数据{15,12,49,16, 36, 40}进行排序。在对各位数进行排序之后,其结果为{40,12,15, 16,36,49},在对十位进行排序之后,其结果为{12,15,16,36,40,49}。有一点非常重要,在对每一位数值进行排序时其排序过程必须是稳定的。因为,一旦一个数值通过较低有效位的值进行排序之后,此数据的位置不应该改变,除非经过较高有效位的值进行比较后需要它调整位置。
基数排序实质上是在元素每一位上应用计数排序来对数据集合排序。从最低位开始,一个位置一个位置地应用计数排序来不断的调整元素。一旦调整完了最高有效位的数值,排序过程完成。获取每位数值的简单方法是使用幂运算和模运算。
基数排序的实现
// RadixSort.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <malloc.h>
#include "typedef.h"
/*
*函数名:RadixSort
*参数:pData 待排序数组数据的首地址
* uiSize 数据的元素个数
* p 待排序元素的位数
* k 基数
*功能:对数组进行基数排序
*返回值:无
*作者:AlbertoNo1
*日期:2016-03-29
*/
VOID RadixSort(VOID *pData, UINT32 uiSize, UINT32 p, UINT32 k)
{
INT32 i = 0;
INT32 j = 0;
INT32 n = 0;
UINT32 uiIndex = 0; //元素在有序数组中的偏移值
UINT32 uiPval = 0;
UINT32 *puiData = NULL;
UINT32 *puiTemp = NULL;
UINT32 *puiCount = NULL;
if (uiSize <= 1)
{/*不用排序*/
return ;
}
/*申请用于存放排序元素的内存*/
puiTemp = (UINT32*)malloc(uiSize*sizeof(UINT32));
if (NULL == puiTemp)
{
return ;
}
/*申请用于存放元素计数数组的内存*/
puiCount = (UINT32*)malloc(k*sizeof(UINT32));
if (NULL == puiCount)
{
free(puiTemp);
return ;
}
puiData = (UINT32*)pData;
for (n = 0; n < p; n++)
{
/*初始化计数频率数组*/
for (j = 0; j < k; j++)
{
puiCount[j] = 0;
}
uiPval = (UINT32)pow((double)k, (double)n);
/*按位统计每个元素出现的频率*/
for (i = 0; i < uiSize; i++)
{
uiIndex = (puiData[i]/uiPval)%k;
puiCount[uiIndex] += 1;
}
/*调整计数值*/
for (j = 1; j < k; j++)
{
puiCount[j] = puiCount[j] + puiCount[j-1];
}
/*排序, 从后往前进行排序,保证了排序的稳定性*/
for (i = uiSize-1; i >= 0; i--)
{
uiIndex = (puiData[i]/uiPval)%k;
memcpy(&puiTemp[puiCount[uiIndex]-1], &puiData[i], sizeof(UINT32));
puiCount[uiIndex] -= 1;
}
memcpy(puiData, puiTemp, uiSize*sizeof(UINT32));
}
free(puiTemp);
free(puiCount);
return ;
}
int _tmain(int argc, _TCHAR* argv[])
{
INT32 iRet = 0;
UINT32 uiLoop = 0;
//UINT32 auiData[] = {10,15,15,18,20,20,20,36,48,51,51,77,77};
UINT32 auiData[] = {77,77,51,51,48,36,20,20,20,18,15,15,10};
//UINT32 auiData[] = {77,15,20,18,51,51,36,10,77,15,20,20,48};
//UINT32 auiData[] = {77,77};
//UINT32 auiData[] = {77};
RadixSort(auiData, sizeof(auiData)/sizeof(auiData[0]), 2, 10);
printf("Radix Sort Success.\n");
printf("Result:\n");
for (uiLoop = 0; uiLoop < sizeof(auiData)/sizeof(auiData[0]); uiLoop++)
{
printf("%d ", auiData[uiLoop]);
}
getchar();
return 0;
}