HDU-1106 快排模板 和 基数排序

45 篇文章 0 订阅

基数排序:

基数排序是一种线性的排序算法。设n个元素不超过d位,而且每位都介于0到9之间。基本思想是把最高位或(最低位)的数字看做第一关键字,次高位(次低位)数字看作是排序的第二关键字,一次类推..。

  比如: 26 25 43 12 5 33    (按着次低位)

先有十个桶:0 1 2  3  4  5  6  7  8  9  或m个桶0<m<=10;

按个位 --->    (12)    (33 ,43)    (25,5)    (26)    最低的位数一次放入相应的编号的桶里。

再一次取出:12 33 43  25 5 26.

在按十为---> (05)   (12)  (25)  (26)  (33,43)     记住是在上次的基础上,一次放入桶里。

取出:5 12 25 26 33 43 。排序就结束了。

可以看出排序的时间复杂度与最高位有关,故有:O(d(n+radix)

代码实现:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

void RadixCountSort(int *npidex,int *npdate,int n) //统计基数个数并排序(桶排序) 
{		  
	int i,npcount[10];             //基数只有十个 (十个桶) 
	memset(npcount,0,sizeof(npcount));
	for(i=0;i<n;i++) npcount[npidex[i]]++;		//统计基数相同的个数。 
	for(i=1;i<10;i++) npcount[i]+=npcount[i-1];	//确定不大于该位置i的个数 
		
	int *npsort=new int[n];
	
	for(i=n-1;i>=0;i--) npsort[--npcount[npidex[i]]]=npdate[i];	//按桶的编号放入	
	for(i=0;i<n;i++) npdate[i]=npsort[i];   //依次从小到大取出桶里的数 
		
	delete npsort;
}

void RadixSort(int *npDate,int n) //基数排序 
{
	int *npDateRadix=new int[n];
	int base=1,flag=0;
	while(flag==0){
		flag=1;
		base*=10;
		for(int i=0;i<n;i++){
		 npDateRadix[i]=npDate[i]%base;
		 npDateRadix[i]/=base/10;
		 if(npDateRadix[i]>0) flag=0;
		}
		if(flag) break;              //如果最大的数的第一个位数为零,排序结束。 
		RadixCountSort(npDateRadix,npDate,n);
	}
	delete npDateRadix;
	return;	
}

int  main(){
	int n,date[1000];
	while(cin>>n){
		for(int i=0;i<n;i++)
		  cin>>date[i];
		RadixSort(date,n);
		for(int i=0;i<n;i++)
		printf("%d ",date[i]);
		printf("\n");
	}
	return 0;
}
/*
12
234 232 34 64 24 6765 13 466 13 99 2546 5
*/

学以致用:下面以HDU·1106为列。看下基数排序的速度。

基数排序(0ms)  快排(0ms)能自己否手写快排?

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

void RadixCountSort(int *npidex,long long *npdate,int n) 
{		  
	int i,npcount[10];              
	memset(npcount,0,sizeof(npcount));
	for(i=0;i<n;i++) npcount[npidex[i]]++;	
	for(i=1;i<10;i++) npcount[i]+=npcount[i-1];	 
		
	int *npsort=new int[n];
	
	for(i=n-1;i>=0;i--) npsort[--npcount[npidex[i]]]=npdate[i];		
	for(i=0;i<n;i++) npdate[i]=npsort[i];   
		
	delete npsort;
}

void RadixSort(long long *npDate,int n)
{
	int *npDateRadix=new int[n];
	int base=1,flag=0;
	while(flag==0){
		flag=1;
		base*=10;
		for(int i=0;i<n;i++){
		 npDateRadix[i]=npDate[i]%base;
		 npDateRadix[i]/=base/10;
		 if(npDateRadix[i]>0) flag=0;
		}
		if(flag) break;              
		RadixCountSort(npDateRadix,npDate,n);
	}
	delete npDateRadix;
	return;	
}
int main()
{
	char st[1005],*p;
	int i,num,flag,cnt;
	long long a[1005];
	while(scanf("%s",st)!=EOF){
		memset(a,0,sizeof(a));
		cnt=0,flag=0,num=0;
	    for(p=st;*p;p++){
			if(*p!='5'){
				num=num*10+(*p-'0');
				flag=1;
			}
			else{
				if(flag){
					a[cnt++]=num;
					num=0;
					flag=0;
				}
			}
	    }
		if(num) a[cnt++]=num;
	//	sort(a,a+cnt);             
	    RadixSort(a,cnt);
		for(i=0;i<cnt;i++)
		printf(i==0?"%d":" %d",a[i]);
		printf("\n");
	}
} 
贴下快排函数的代码:

#include <stdio.h>

int patition(int a[], int p, int r) //模板
{
	int i = p-1;
	for (int j = p; j <= r-1; ++j) 
	{
		if (a[j] < a[r]) 
		{
			++i;
			int t = a[i];
			a[i] = a[j];
			a[j] = t;	
		}
	}
	int t = a[i+1];
	a[i+1] = a[r];
	a[r] = t;
	return i+1;
} 

 void quicksort(int a[], int p, int r)
 {
	if (p < r) 
	{
		int q = patition(a, p, r);
		quicksort(a, p, q-1);
		quicksort(a, q+1, r);
	}
}

int main()
 {
	int N,A[1000];
	while (1)
	{
		printf("请输入要排序的元素个数:");
		scanf("%d", &N); 
		for (int i = 1; i <= N; ++i) 
			scanf("%d", &A[i]);
		quicksort(A, 1, N);
		for ( i = 1; i <= N; ++i) 
			printf("%d ", A[i]);	
		puts(""); 
	}
	return 0;	
}

总的来说基数排序要稍好于快排。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值