数据结构与算法分析 #3 基数排序

基数排序

桶式排序

在了解、实现基数排序前,先要了解桶式排序。个人理解概括如下:
若有一组待排序的数data,已知其范围从0~m。则可申请大小为m的数组,初始化元素为0,将待排序数依次扫描,并将其数对应下标的数组元素置1,最后扫描数组由小到大(或由大到小)输出元素值为1的下标。


从上面前导的桶式排序已经可以看出,基于桶式排序的基数排序,是以空间换时间的排序算法。其运行时间为O(P(N+B)),P为排序的趟数,N为被排序的元素的个数。为了实现时间短的排序,基数排序会申请n*x个的地址空间作为容器进行排序(n为数据基数,此处为十进制记,x为待排序数据个数),空间开销大。

基数排序个人概述如下:
设i为数位,i=0,即从个位起,根据待排序数的第i位进行排序进行桶式排序,并将排序后数重新写入待排序数。循环直到i>数据中的最高位。

//巧妙运用自增减可简化代码

个人代码如下(数组实现):

//开始肛吧 数组版基数排序
#include<stdlib.h>
#include<stdio.h>

#define DEBUG 1
#define Cardinal 10//以10为基数
#define MaxPower 10//待排序数中以10为底的最高幂

/*传入整数n及整数pos,传出n中第pos位的值*/
/*pos从第0位开始计*/
int numofposition(int n, int pos)
{
	int pospower=1;
	for (int i = 0; i < pos; i++)
		pospower *= 10;
	return n / pospower % 10;
}

/*传入待排序数组 数组元素个数*/
void Cardinal_Sort(int array[], int totalnum)
{
	int i;
	int *temp_array[Cardinal];//建立基数排序0-9的桶
	for (i = 0; i < Cardinal; i++)
	{
		temp_array[i] = (int*)malloc(sizeof(int)*(totalnum + 1));//对每一个基数的桶申请数组个数+1的空间(建立动态二维数组)
		temp_array[i][0] = 0;
	}

	for (i = 0; i < MaxPower; i++)
	{
		/*对data的第i位数进行桶式排序*/
		for (int m, j = 0; j < totalnum; j++)
		{
			int order;
			m=numofposition(array[j], i);//判断第i位上的数是多少
			temp_array[m][0]++;
			order = temp_array[m][0];
			temp_array[m][order] = array[j];//找到i位上数对应的桶,将data按该桶内数组的次序填入

#ifdef DEBUG
		//	printf("桶式排序:%d \n", temp_array[m][order]);
#endif // DEBUG

		}

		/*将排好的数从新读入data数组*/
		for (int g=0, j = 0; j < Cardinal; j++)
		{
			for (int k = 1; k <= temp_array[j][0]; k++)
			{
				array[g++] = temp_array[j][k];//巧妙利用自增
#ifdef DEBUG
				printf("数据数:%d 填入数据: %d\n", temp_array[j][0], temp_array[j][k]);
#endif // DEBUG

			}
			temp_array[j][0] = 0;//复位
		}

#ifdef DEBUG
		for (int i = 0; i < totalnum; i++)
			printf("%d\t", array[i]);
		printf("\n");
#endif // DEBUG


	}

}

int main()
{
	int testarray[10] = { 531,310,72,373,15,546,385,856,187,147 };
	int num = 10;
	int i;
	for (i = 0; i < num; i++)
		printf("%d\t", testarray[i]);
	printf("\n");
	Cardinal_Sort(testarray, num);
	for (i = 0; i < num; i++)
		printf("%d\t", testarray[i]);

	system("pause");
	return 0;
}
看懂了下方链接的单链表实现方式,不依靠循环而是靠拼接表头表尾,学习了。关于指针的学习之路漫漫修远兮。


参考博客:

感谢这些博主,你们都是我踽踽独行学习编程路上的老师。从你们代码中受益匪浅。
基数排序的数组实现:https://blog.csdn.net/cjf_iceking/article/details/7943609
桶式排序的链表实现:https://blog.csdn.net/LG1259156776/article/details/48803043
基数排序的链表实现:https://blog.csdn.net/Shayabean_/article/details/44885917

猜你喜欢

转载自blog.csdn.net/weixin_40505645/article/details/80109367