算法导论8-3变长数据项排序-整数数组-字符串

//算法导论8-3,变长数据项的排序
#include <iostream>
#include <ctime>
#include <boost/timer/timer.hpp>
using namespace std;
using namespace boost::timer;

int bits(int i)//找出每位数的位数,正数为正,负数为负
{
	int radix=1;
	while (i/10)
	{
		radix++;
		i/=10;
	}
	return (i>=0)?radix:(-radix);
}

void find_max_min(int *aCount,int &max,int &min,int n)
{//查找数字的最大位数
	max=aCount[0];//初始化
	min=max;
	int tmp;
	for(int i=1;i<n;++i){
		tmp=aCount[i];
		if(max<tmp){
			max=tmp;
		}else if(min>tmp){
			min=tmp;
		}
	}
}
void radix_sort(int *bucket,int n)//基数排序
{
	int *s=new int[n];
	int bit=abs(bits(bucket[0]));//此处用正数
	int radix=1;
	int *b=new int[n];
	for(int i=0;i<bit;++i,radix*=10){
		for(int j=0;j<n;++j){
			s[j]=(bucket[j]/radix)%10;//存储每轮的值
		}		
		int max,min;
		find_max_min(s,max,min,n);
		int count=max-min+1;
		int *c=new int[count];
		memset(c,0,count*sizeof(int));
		for(int j=0;j<n;++j){
			c[s[j]-min]++;
		}
		for(int j=1;j<count;++j){
			c[j]+=c[j-1];
		}

		for(int j=n-1;j>=0;--j){
			b[c[s[j]-min]-1]=bucket[j];
			c[s[j]-min]--;
		}
		/*for(int j=0;j<n;++j){
			bucket[j]=b[j];
		}*/
		memcpy(bucket,b,n*sizeof(int));
		delete[]c;
	}
	delete[]b;
	delete[]s;
}

void bucket_sort(int *a,int n)//桶排序
{
	int *aCount=new int[n];//记录a[i]的位数
	for(int i=0;i<n;++i){
		int bit=bits(a[i]);//位数
		aCount[i]=bit;
	}

	int max,min;
	find_max_min(aCount,max,min,n);
	int count=max-min+1;
	int *b=new int[count];//用来存放不同位数的数字的个数
	memset(b,0,count*sizeof(int));//初始化为零

	for(int i=0;i<n;++i){//统计每个桶的元素个数
		b[aCount[i]-min]++;
	}

	int **bucket=new int *[count];
	int *flag=new int [count];
	for(int i=0;i<count;++i){
		bucket[i]=new int[b[i]];//第i个桶有b[i]个元素
		flag[i]=0;//初始化
	}

	for(int i=0;i<n;++i){//将相关元素放到相应的桶中
		bucket[aCount[i]-min][flag[aCount[i]-min]++]=a[i];
	}

	int k=0;
	for(int i=0;i<count;++i){
		radix_sort(bucket[i],b[i]);
		for(int j=0;j<b[i];++j){
			a[k++]=bucket[i][j];
		}
	}
}


int main()
{
	srand(time(NULL));
	int count;
	while (count=rand()%16,count<4);
	count=100;
	int *a=new int[count];
	for(int i=0;i<count;++i){
		a[i]=rand()%201-100;
		cout<<a[i]<<"\t";
	}
	//a[0]=-2,a[1]=-5,a[2]=-3,a[3]=1,a[4]=-2;
	cout<<endl;
	cpu_timer t1;
	t1.start();
	bucket_sort(a,count);
	t1.stop();

	for(int i=0;i<count;++i){
		cout<<a[i]<<"\t";
	}
	cout<<endl;
	delete[]a;
	cout<<t1.format();
}

#include <iostream>
#include <ctime>
#include <boost/timer/timer.hpp>
using namespace std;
using namespace boost::timer;
void find_max_min(char **str,int &max,int &min,int index,int offset,int n)
{
	max=str[offset][index],min=str[offset][index];
	for(int i=1;i<n;++i){
		if(max<str[i+offset][index]){
			max=str[i+offset][index];
		}else if(min>str[i+offset][index]){
			min=str[i+offset][index];
		}
	}
}

int insertion_sort_stable(char **str,int index,int offset,int n){//插入排序版本,对元素按照长短进行排序
	int key,j;
	int num=(strlen(str[offset])==index)?1:0;
	for(int i=1;i<n;++i){
		if((key=strlen(str[i+offset]))==index){
			num++;
		}
		char *keystr=str[i+offset];
		j=i-1;
		while (j>=0 && strlen(str[j+offset])>key){
			str[j+1+offset]=str[j+offset];
			--j;
		}
		str[j+1+offset]=keystr;
	}
	return num;
}

int fast_sort_unstable(char **str,int index,int offset,int n)//快速排序版本,将字符串等于index的放在前面
{
	int p=-1;
	char *keystr;
	for(int i=0;i<n;++i){
		if(strlen(str[offset+i])==index){
			p++;
			keystr=str[i+offset];
			str[i+offset]=str[offset+p];
			str[offset+p]=keystr;
		}
	}
	return p+1;
}



void counting_sort(char **str,int index,int offset,int n)//计数排序
{
	char **strCpy=new char *[n];//临时存储字符串
	int max,min;
	find_max_min(str,max,min,index,offset,n);
	int count=max-min+1;
	int *c=new int[count];
	memset(c,0,count*sizeof(int));
	for(int i=0;i<n;++i){
		c[str[i+offset][index]-min]++;
	}
	int tmp=c[count-1];//存储最后一组的元素个数值

	for(int i=1;i<count;++i){
		c[i]=c[i]+c[i-1];
	}
	for(int i=n-1;i>=0;--i){
		//strCpy[c[str[i+offset][index]-min]-1]=new char[strlen(str[i+offset])+1];//初始化内存空间
		//memcpy(strCpy[c[str[i+offset][index]-min]-1],str[i+offset],strlen(str[i+offset])+1);
		strCpy[c[str[i+offset][index]-min]-1]=str[i+offset];		
		c[str[i+offset][index]-min]--;//每组字符个数减1
	}
	for(int i=0;i<n;++i){
		//memcpy(str[i+offset],strCpy[i],strlen(strCpy[i])+1);
		str[i+offset]=strCpy[i];
	}
	
	for(int i=0;i<count-1;++i){
		c[i]=c[i+1]-c[i];//恢复原始每组元素值
	}
	c[count-1]=tmp;

	int dd;//存储每组相同元素的个数
	for(int i=0;i<count;++i){
		if(i!=0){
			c[i]=c[i]+c[i-1];
		}
		dd=(i>0)?(c[i]-c[i-1]):c[0];
		if(dd>1){
			int k=(i>0)?c[i-1]:0;
			//int num = insertion_sort_stable(str,index+1,offset+k,dd);//返回可忽略的数字
			int num=fast_sort_unstable(str,index+1,offset+k,dd);//返回可忽略的数字			
			/*for(int j=0;j<dd;++j){				
			cout<<str[offset+k+j]<<"\t";
			}
			cout<<endl;*/
			counting_sort(str,index+1,offset+k+num,dd-num);//递归调用
		}
	}
	delete [] strCpy;
	delete[]c;
}


int main()
{
	srand(time(NULL));
	int count;
	while (count=rand()%100,count<50);
	count=40000000;
	char **str=new char*[count];
	int size;
	for(int i=0;i<count;++i){
		while (size=rand()%10,size<2);
		str[i]=new char[size];
		int j=0;
		while (j<size-1){//随机生成字符串
			str[i][j]=rand()%26+'A'+(rand()%2)*32;//随机生成字母
			++j;
		}
		str[i][j]='\0';
	}
	/*str[0]=new char [2];
	str[1]=new char [3];
	str[2]=new char [4];
	strcpy(str[2],"a");
	strcpy(str[0],"a");
	strcpy(str[1],"ab");

	for(int i=0;i<count;++i){
		cout<<str[i]<<"\t";
	}
	cout<<endl;*/
	cout<<endl<<"*******************************"<<endl;
	cout<<count<<" strings"<<endl;
	cpu_timer t1;
	t1.start();
	counting_sort(str,0,0,count);
	t1.stop();
	cout<<endl<<"*******************************"<<endl;
	//for(int i=0;i<count;++i){
	//	cout<<str[i]<<"\t";
	//}
	//cout<<endl;
	cout<<t1.format();
	for(int i=0;i<count;++i){
		delete [] str[i];
		//str[i]=NULL;
	}
	delete[] str;
}

操作系统自带的qsort排序实习定长字符数组排序

#include <iostream>
#include <algorithm>
#include <boost/timer/timer.hpp>
#include <ctime>
using namespace std;
using namespace boost::timer;

int compar_words(const void *p, const void *q)
{
	return strcmp(*(char **)p, *(char **)q);
}
int main()
{
	srand(time(NULL));
	int count;
	while (count=rand()%100,count<50);
	count=40000000;
	char **str=new char*[count];
	int size=5;
	for(int i=0;i<count;++i){
		while (size=rand()%20,size<2);
		size=5;
		str[i]=new char[size];
		int j=0;
		while (j<size-1){//随机生成字符串
			str[i][j]=rand()%26+'A'+(rand()%2)*32;//随机生成字母
			++j;
		}
		str[i][j]='\0';
	}
	cout<<"*******************************"<<endl;
	cout<<count<<" strings"<<endl;
	cpu_timer t1;
	t1.start();
	qsort(str,count,sizeof(str[0]),compar_words);
	cout<<"*******************************"<<endl;
	t1.stop();
	cout<<t1.format();
	for(int i=0;i<count;++i){
		delete[] str[i];
	}
	delete[] str;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值