排序算法(九):基数排序

一、算法原理
基数排序(Radix sort)是用在卡片排序机上的算法,是一种非比较的排序算法。基数排序对十进制数的每一位进行排序,与直观感受不同的是,先按最低有效位进行排序,然后收集;再按次低位排序,再收集;依此类推,直到按最高位进行排序收集之后,数组整体完成排序。为了确保基数排序的正确性,每一位的排序算法必须是稳定的(例如,若a=b,排序后a与b的顺序不发生改变)。

二、算法描述

  • 首先,找到数组中的最大数,并确定其十进制位数d;
  • 然后,从最低位开始取每个位组成Radix数组,对这个数组进行计数排序,每一位的取值范围在[0…k]内;
  • 按照Radix排序的顺序,将原数组排序
  • 直到按最高位排完序之后,原数组整体排序完成

三、算法复杂度

  • 时间复杂度:T(n) = O(d*n)
  • 空间复杂度:O(n),即需要额外辅助空间,与原数组规模成正比
void CountSort(int A[], int length, int d);  //函数原型
//基数排序,A是待排序数组,d是A中元素的最大十进制位数
void RadixSort(int A[], int length, int d)
{
	if(A == NULL || d <= 0)
	{
		printf("Input error!\n");
		return;
	}
	
	//从最低位开始,每一位应用计数排序
	for(int i = 1; i <= d; ++i)
	{
		CountSort(A, length, i);  //采用计数排序,按照每一位进行排序
	}
}

//计数排序,数组A的值在0~9范围内,d是待排序的十进制位数,数组B存放排序后的数组
void CountSort(int A[], int length, int d)
{	
	//建立辅助数组Ad[],存放A每一个元素的第d位数
	int Ad[length];
	int dd = 1;
	for(int i = 1; i < d; i++)
	{
		dd *= 10;
	}
	for(int i = 0; i < length; i++)
	{
		if(d == 1)
		{
			Ad[i] = A[i] % 10;
		}
		else
		{
			Ad[i] = (A[i]/dd) % 10;
		}
	}
	
	//初始化B和C数组
	int B[length];
	for(int i = 0; i < length; i++)
		B[i] = 0;
	
	int C[10];
	for(int i = 0; i < 10; i++)
	{
		C[i] = 0;
	}
	
	//C数组对Ad数组中元素进行计数
	for(int j = 0; j < length; j++)
	{
		C[Ad[j]]++;
	}
	
	//将C数组计数次数每一项与前一项累加
	for(int i = 1; i <= 9; i++)
	{
		C[i] = C[i-1] + C[i];
	}
	
	//在B数组中保存排序好的数组
	for(int j = length - 1; j >= 0; j--)
	{
		B[C[Ad[j]]-1] = A[j];
		C[Ad[j]]--;
	}
	
	//将A数组更新为排序后的数组
	for(int i = 0; i < length; i++)
	{
		A[i] = B[i];
	}	
}


你可能感兴趣的:(C,算法)