基数排序(桶排序)--静态链表实现

原理

      基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。

      基数排序的主要思路:将所有待比较数值(注意,必须是正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始, 依次进行一次稳定排序(注意必须是稳定的),这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

实现方法

最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。

最低位优先(Least Significant Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。

LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。这里以LSD法为例。

具体实现

#include<cstdio>
#include<cstdlib>
using namespace std;

typedef struct node{              //定义结点
	int data;                       
	int next;                     //静态链表,空指针默认为-1
}Node;

int data[101];                    //待排序的数组   
Node bucket[10];                  //桶数组
Node d[101];                      //将待排序的数组构造成Node类型的数组
int n;                            //待排序数组的数的个数

int getdigit(){                   //获取数组中最多的位数
	int max=1;
	for(int i=0;i<n;i++){
		int x=data[i];
		int num=1;
		while(x/10){
			x/=10;
			num++;
		}
		if(num>max)
			max=num;
	}
	return max;
}

void init(){                      //清空桶数组和d数组
	for(int i=0;i<10;i++){
		bucket[i].data=i;
		bucket[i].next=-1;
	}
	for(int i=0;i<n;i++){
		d[i].data=data[i];        //将data数组中的数顺序地赋给d数组
		d[i].next=-1;
	}
}

void Radixsort(){
	int digit=getdigit();         //数组中的数的位数的最大值
	int key=1;
	for(int i=0;i<digit;i++){     //装桶,出桶的次数
		init();
		for(int i=n-1;i>=0;i--){  //按从大到小的顺序装桶
			int a=(d[i].data/key)%10;
			d[i].next=bucket[a].next;
			bucket[a].next=i;
		}
		int b=0;                  
		for(int i=0;i<10;i++){    //对桶数组从上到下出桶到data数组中去
			if(bucket[i].next!=-1){
				int p=bucket[i].next;
				data[b++]=d[p].data;
				while(d[p].next!=-1){
					data[b++]=d[d[p].next].data;
					p=d[p].next;
				}
			}
		}
		key*=10;                   //key值乘以10
	}
}

void print(){                      //输出数组
	for(int i=0;i<n;i++)
		printf("%d ",data[i]);
	printf("
");
}

int main(){
	printf("Please input the size of array:");
	scanf("%d",&n);                //输入数组元素的个数
	for(int i=0;i<n;i++)
		scanf("%d",&data[i]);
	Radixsort();
	print();
	return 0;	
}
原文地址:https://www.cnblogs.com/FrankChen831X/p/10326081.html