基数排序(c/c++)

基数排序不同前面的各种排序,它并不基于比较排序,而是采用多关键字排序。通常,按照低位至高位的顺序进行排序的,也就是最低位优先(LSD)。

本文也是采用最低位优先排序,代码是对简单的两位数进行基数排序,所采用的存储结构为二维数组,仅为说明基数排序的思想。在此基础上便可以进行多位数的排序,也可以采用链表进行存储,都是可以的。

计数排序过程可粗略的看为 分配-收集,分配-收集,.....,以最低位优先为例,第一次分配是按照数列的个位数分配到给定的存储结构中,分配好所有数之后,按顺序从存储结构一个个收集;第二次分配是按照数列的十位数进行分配,然后收集;再分配百位数,再收集......如对数列  7 10 46 31 29 30进行基数排序:

第一趟分配结果为(10,30),(31),(46),(7),(29)

第一趟收集结果为  10 30 31 46 7 29

第二趟分配结果为(7),(10),(29),(30,31),(46)

第二趟收集结果为  7 10 29 30 31 46      排序结束。

注:存储结构中应该是按照基数0~9排列的,而数列没有个位是2的数,如第一趟分配结果完整描述为:

(10,30),(31),(),(),(),(),(46),(7),(),(29)

基数排序的时间复杂度为 d趟分配和收集所需的时间,一趟分配的时间为o(n),一趟收集的时间最大为o(n+r),r为基数,本文中r为10。故其时间复杂度最大为o(d*(2n+r)); 空间复杂度最大为o(n+r);基数排序是稳定的。

完整代码如下:

#include
#include
#define N 20
void baseSort(int* arr, int num);
int back[10][10];//存储空间
int main()
{
	int a[N] = { 3, 2, 4, 6, 7, 5, 18, 9, 10, 1,
		16, 8, 20, 33, 28, 64, 19, 31, 30, 25 };
	for (int i = 0; i < N; i++)
	{
		std::cout << a[i] << "  ";
	}
	std::cout << '\n';
	baseSort(a, N);
	for (int i = 0; i < N; i++)
	{
		std::cout << a[i] << "  ";
	}
	std::cout << '\n';
	return 0;
}

void baseSort(int* arr, int num)
{
	int i, j, temp;  
	for (i = 0; i < num; i++)//按个位分配
	{
		j = 0;
		temp = arr[i] % 10;
		while (back[temp][j] != 0)
			++j;
		back[temp][j] = arr[i];
	}
	j = 0;
	for (i = 0; i < 10; i++)//回收
	{
		temp = 0;
		while(back[i][temp] != 0)
			arr[j++] = back[i][temp++];
	}

	memset(back, 0, 400);//二维数组清零
	for (i = 0; i < num; i++)//按十位分配
	{
		j = 0;
		temp = arr[i] / 10;
		while (back[temp][j] != 0)
			++j;
		back[temp][j] = arr[i];
	}
	j = 0;
	for (i = 0; i < 10; i++)//回收
	{
		temp = 0;
		while (back[i][temp] != 0)
			arr[j++] = back[i][temp++];
	}
}

 

你可能感兴趣的:(数据结构与算法)