各种排序算法练习
Posted 禾小白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了各种排序算法练习相关的知识,希望对你有一定的参考价值。
最近忙着准备找工作,把之前写的排序算法整理下,写到一起,方便以后用,废话不说,直接上代码;
#include<iostream> #include<time.h> using namespace std; #define N 100 //#define SWAP(x,y){int t;t=x;x=y;y=t;} #define SWAP(x,y) {x=x^y;y=x^y;x=x^y;} //基数排序 void radixsort(int data[], int n) { //辅助函数,求数据的最大位数 int d = 1; //保存最大的位数 int p = 10; for(int i = 0; i < n; ++i) { while(data[i] >= p) { p *= 10; ++d; } } //基数排序 int *tmp = new int[n]; int *count = new int[10]; //计数器 int i, j, k; int radix = 1; for(i = 1; i <= d; i++) //进行d次排序 { for(j = 0; j < 10; j++) count[j] = 0; //每次分配前清空计数器 for(j = 0; j < n; j++) { k = (data[j] / radix) % 10; //统计每个桶中的记录数 count[k]++; } for(j = 1; j < 10; j++) count[j] = count[j - 1] + count[j]; //将tmp中的位置依次分配给每个桶 for(j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中 { k = (data[j] / radix) % 10; tmp[count[k] - 1] = data[j]; count[k]--; } for(j = 0; j < n; j++) //将临时数组的内容复制到data中 data[j] = tmp[j]; radix = radix * 10; } delete[]tmp; delete[]count; } //shell排序,改进的插入排序 int shellsort(int *number) { for(int group=N/2;group>0;group/=2) { for(int i=group;i<N;i++)//每一个都循环,所以下面每次只交换一次 { for(int j=i-group;j>=0&&(number[j]>number[j+group]);j-=group)//每次只能交换一次,交换多了就不对了 { SWAP(number[j],number[j+group]); } } } return 0; } //插入排序 int insort(int *number) { /*int temp; for(int i=N-2;i>=0;i--)//从大到小循环进行排序 { temp=number[i]; int j=i+1; while(temp>number[j]) { number[j-1]=number[j]; j++; if(j==N) break; } number[j-1]=temp; }*/ int temp,j; for(int i=1;i<N;i++)//从小到大循环进行排序 { temp=number[i]; for(j=i;j>0;j--) { if(number[j-1]>temp) { number[j]=number[j-1]; } else { break; } } number[j]=temp; } return 0; } //heap算法,堆排序,改进的选择排序 int heapsort(int *number) { //建立排序堆积树 int heap[N+1]={-1111},child,parent; for(int i=1;i<=N;i++) { heap[i]=number[i-1]; child=i; parent=i/2; while(heap[child]<heap[parent]&&child>=2)//子树比根小并且有子树 { SWAP(heap[child],heap[parent]); child=parent; parent=child/2; } } //堆排序 int n=N; while(n>1) { number[N-n]=heap[1]; SWAP(heap[1],heap[n]); n--; parent=1; child=2*parent; while(child<=n) { if(child<n&&heap[child]>heap[child+1])//有两个子树并右子树较小或 child++; if(heap[parent]<=heap[child])//根比子树小 break; SWAP(heap[parent],heap[child]); parent=child; child=2*parent; } } number[N-1]=heap[1]; return 0; } //选择排序 int selsort(int *number) { int temp; for(int i=0;i<N;i++) { int min=9999; for(int j=i;j<N;j++) { if(min>number[j]) { min=number[j]; temp=j; } } number[temp]=number[i]; number[i]=min; } return 0; } //shaker排序,改进的冒泡排序 int shakersort(int *number) { int left=0,right=N-1,i; int shift=left; while(left<right) { for(i=left;i<right;i++) { if(number[i]>number[i+1]) { SWAP(number[i],number[i+1]); shift=i; } } right=shift; for(i=right;i>left;i--) { if(number[i]<number[i-1]) { /*temp=number[i]; number[i]=number[i-1]; number[i-1]=temp;*/ SWAP(number[i],number[i-1]); shift=i; } } left=shift; } return 0; } //冒泡排序 int bubsort(int *number) { //int temp; for(int i=0;i<N-1;i++) { for(int j=0;j<N-i-1;j++) { if(number[j]>number[j+1]) { SWAP(number[j],number[j+1]); } } } return 0; } //快速排序1(最左为轴) void quicksort1(int *number,int left,int right) { int s,i,j; if(left<right) { s=number[left],i=left,j=right+1; while(1) { while(i+1<right+1&&number[++i]<s) ; while(j-1>left-1&&number[--j]>s) ; if(i>=j) break; SWAP(number[i],number[j]); } number[left]=number[j]; number[j]=s; quicksort1(number,left,j-1); quicksort1(number,j+1,right); } } //快速排序2(中间为轴) void quicksort2(int *number,int left,int right) { int i,j,s; if(left<right) { s=number[(left+right)/2],j=right+1,i=left-1; while(1) { while(number[++i]<s) ; while(number[--j]>s) ; if(i>=j) break; SWAP(number[i],number[j]); } quicksort2(number,left,i-1); quicksort2(number,j+1,right); } } //算法导论书 void quicksort3(int *number,int left,int right) { int i,j,s,q; if(left<right) { s=number[right]; i=left-1; for(j=left;j<right;j++) { if(number[j]<=s)//当两个数一样的时候交换后为0 { i++; if(number[i]!=number[j]) //cout<<number[i]<<‘ ‘<<number[j]<<endl; SWAP(number[i],number[j]); //cout<<number[i]<<‘ ‘<<number[j]<<endl; } } if(number[i+1]!=number[right]) SWAP(number[i+1],number[right]); q=i+1; quicksort3(number,left,q-1); quicksort3(number,q+1,right); } } //归并排序 int mergeSort(int *data, int p, int r) { int q; int n1, n2, i, j, k; if(p < r) //只有一个或无记录时不须排序 { q = (int)((p+r)/2); //将data数组分成两半 mergeSort(data, p, q); //递归拆分左数组 mergeSort(data, q+1, r); //递归拆分右数组 //*************************合并数组 int *left=NULL, *right=NULL; n1 = q-p+1; n2 = r-q; left = (int *)malloc(sizeof(int)*(n1)); right = (int *)malloc(sizeof(int)*(n2)); //检查是否分配成功 if(left==NULL||right==NULL){ cout<<"归并排序分配内存错误!!!"<<endl; return 0; } for(i=0; i<n1; i++) //对左数组赋值 left[i] = data[p+i]; for(j=0; j<n2; j++) //对右数组赋值 right[j] = data[q+1+j]; i = j = 0; k = p; while(i<n1 && j<n2) //将数组元素值两两比较,并合并到data数组 { if(left[i] <= right[j]) data[k++] = left[i++]; else data[k++] = right[j++]; } for(; i<n1; i++) //如果左数组有元素剩余,则将剩余元素合并到data数组 data[k++] = left[i]; for(; j<n2; j++) //如果右数组有元素剩余,则将剩余元素合并到data数组 data[k++] = right[j]; free(left); free(right); left=NULL; right=NULL; //当不需要再使用申请的内存时,记得释放; //释放后应该把指向这块内存的指针指向NULL,防止程序后面不小心使用了它。 } return 0; } int selectag() { cout<<"输入0为退出,"<<endl <<"输入1为冒泡排序,"<<endl <<"输入2为选择排序,"<<endl <<"输入3为插入排序,"<<endl <<"输入4为希尔排序(改进的插入排序),"<<endl <<"输入5为Shaker排序(改进的冒泡排序),"<<endl <<"输入6为heap(堆)排序(改进的选择排序),"<<endl <<"输入7为快速排序1(最左为轴),"<<endl <<"输入8为快速排序2(中间为轴),"<<endl <<"输入9为快速排序3(算法导论),"<<endl <<"输入10为归并排序,"<<endl <<"输入11为基数排序,"<<endl <<"请选择排序算法:"; return 0; } int creatlist(int *number) { int j,temp; for(int i=0;i<N;i++)//随机生成1到N的数组 { j=rand()%N; temp=number[i]; number[i]=number[j]; number[j]=temp; } cout<<"排序前:"<<endl; for(int i=0;i<N;i++) { cout<<number[i]; if(i<N-1) cout<<"->"; } cout<<endl; return 0; } int main() { clock_t start, finish;//开始结束时间 double duration; //耗时 int number[N]; for(int i=0;i<N;i++) number[i]=i; srand((unsigned)time(NULL)); selectag(); int in=1,sortstatus=1;//sortstatus为是否进行了排序 char end;//是否退出循环 int inright=1;//输入正确 while(in!=0) { sortstatus=1; while(inright) { cin.clear();//重置错误输入 cin.sync();//清空缓冲区 不然会出现无限循环 cin>>in; if(!cin.fail())//如果输入不匹配,fail()会返回真 { inright=0; } else { cout<<"**********************输入有误,不是int类型,请输入int数字:"; selectag(); } } start = clock(); //开始计时 switch(in) { case 0: cout<<"**********************确认退出???(y/n)**********************"<<endl; cin.clear(); cin>>end; switch(end) { case ‘y‘:case ‘Y‘: //这里退出,所以不用selectag(); break; case ‘n‘:case ‘N‘: selectag(); inright=1;//重新进行输入检测 sortstatus=0;//这次没有进行排序 in=9999; break; } break; case 1: creatlist(number); bubsort(number); cout<<"冒泡排序:"<<endl; break; case 2: creatlist(number); selsort(number); cout<<"选择排序:"<<endl; break; case 3: creatlist(number); insort(number); cout<<"插入排序:"<<endl; break; case 4: creatlist(number); shellsort(number); cout<<"希尔排序(改进的插入排序):"<<endl; break; case 5: creatlist(number); shakersort(number); cout<<"Shaker排序(改进的冒泡排序):"<<endl; break; case 6: creatlist(number); heapsort(number); cout<<"heap(堆)排序(改进的选择排序):"<<endl; break; case 7: creatlist(number); quicksort1(number,0,N-1); cout<<"快速排序1(最左为轴):"<<endl; break; case 8: creatlist(number); quicksort2(number,0,N-1); cout<<"快速排序2(中间为轴):"<<endl; break; case 9: creatlist(number); quicksort3(number,0,N-1); cout<<"快速排序3(算法导论):"<<endl; break; case 10: creatlist(number); mergeSort(number,0,N-1); cout<<"归并排序:"<<endl; break; case 11: creatlist(number); radixsort(number,N); cout<<"基数排序:"<<endl; break; default: sortstatus=0; inright=1; cout<<"**********************输入有误,请输入正确的数字!!!**********************"<<endl; selectag(); break; } finish = clock(); //结束计时 duration=(double)(finish-start)/CLOCKS_PER_SEC; cout<<"本算法总耗时"<<duration<<endl; if(in!=0&&sortstatus) { for(int i=0;i<N;i++) { cout<<number[i]; if(i<N-1) cout<<"->"; } cout<<endl; selectag(); inright=1; } } system("pause"); return 0; }
以上是关于各种排序算法练习的主要内容,如果未能解决你的问题,请参考以下文章