7-12 排序(25 分)
给定N个(长整型范围内的)整数,要求输出从小到大排序后的结果。
本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下:
- 数据1:只有1个元素;
- 数据2:11个不相同的整数,测试基本正确性;
- 数据3:103个随机整数;
- 数据4:104个随机整数;
- 数据5:105个随机整数;
- 数据6:105个顺序整数;
- 数据7:105个逆序整数;
- 数据8:105个基本有序的整数;
- 数据9:105个随机正整数,每个数字不超过1000。
输入格式:
输入第一行给出正整数N(≤105),随后一行给出N个(长整型范围内的)整数,其间以空格分隔。
输出格式:
在一行中输出从小到大排序后的结果,数字间以1个空格分隔,行末不得有多余空格。
输入样例:
11 4 981 10 -17 0 -20 29 50 8 43 -5
输出样例:
-20 -17 -5 0 4 8 10 29 43 50 981
一 , 冒泡排序(bubble_sort)
1.简单的冒泡排序
1 #include<iostream> 2 using namespace std; 3 void Bubble_sort1(long int data[],int N){ 4 for(int i=0;i<N-1;i++) 5 for(int j=0;j<N-1-i;j++) 6 if(data[j]>data[j+1]){ 7 int t=data[j]; 8 data[j]=data[j+1]; 9 data[j+1]=t; 10 } 11 } 12 int main() 13 { 14 int N=0,flag=0; 15 cin>>N; 16 long int data[N]; 17 for(int i=0;i<N;i++) 18 cin>>data[i]; 19 Bubble_sort(data,N); 20 for(int i=0;i<N;i++) 21 if(flag++==0) 22 cout<<data[i]; 23 else 24 cout<<" "<<data[i]; 25 return 0; 26 }
此法较为简单,但可改良;
测试结果
2.改良的冒泡排序
1 #include<iostream> 2 using namespace std; 3 void Bubble_sort2(long int data[],int N){ 4 for(int i=0;i<N-1;i++){ 5 int flag=0;//改良,防止在循环结束前已排好序,还傻不哝咚的继续做 6 for(int j=0;j<N-1-i;j++) 7 if(data[j]>data[j+1]){ 8 int t=data[j]; 9 data[j]=data[j+1]; 10 data[j+1]=t; 11 flag=1; 12 } 13 if(flag==0) 14 break; 15 } 16 } 17 int main() 18 { 19 int N=0,flag=0; 20 cin>>N; 21 long int data[N]; 22 for(int i=0;i<N;i++) 23 cin>>data[i]; 24 Bubble_sort2(data,N); 25 for(int i=0;i<N;i++) 26 if(flag++==0) 27 cout<<data[i]; 28 else 29 cout<<" "<<data[i]; 30 return 0; 31 }
结果如下
版权声明:本文为博主原创文章,未经博主允许不得转载。
二,插入排序(联想扑克牌)
1 #include<iostream> 2 using namespace std; 3 void Insertion_sort1(long int data[],int N){ 4 int i,j; 5 for( i=1;i<N;i++){ 6 int temp=data[i]; 7 for( j=i;j>0&&temp<data[j-1];j--) 8 data[j]=data[j-1]; 9 data[j]=temp; 10 } 11 } 12 int main() 13 { 14 int N=0,flag=0; 15 cin>>N; 16 long int data[N]; 17 for(int i=0;i<N;i++) 18 cin>>data[i]; 19 Insertion_sort1(data,N); 20 for(int i=0;i<N;i++) 21 if(flag++==0) 22 cout<<data[i]; 23 else 24 cout<<" "<<data[i]; 25 return 0; 26 }
测试结果
版权声明:本文为博主原创文章,未经博主允许不得转载。
三,希尔排序(是插入排序的升级版,通过一次交换两个较远的数来消除不止一个逆序队)
增量序列有希尔增量,Hibbard增量,sedgewick增量等等,据说sedgewick增量效果不错
1 #include<iostream> 2 using namespace std; 3 void shell_sort(long int data[],int N){ 4 long int IncrementSequence_Sedgewick[]={0, 5 1,5,19,41,109,209,505,929, 6 2161,3905,8929,16001,36289,64769,146305,260609, 7 587521,1045505,2354689,4188161,9427969,16764929,37730305,67084289, 8 150958081,268386305,603906049,1073643521}; 9 int i=0,j,k,D; 10 long int temp; 11 for(i=1;IncrementSequence_Sedgewick[i+1]<N;i++); 12 for(D=IncrementSequence_Sedgewick[i];D>0;D=IncrementSequence_Sedgewick[i--]) 13 for(j=D;j<N;j++){ 14 temp=data[j]; 15 for(k=j;k>=D&&data[k-D]>temp;k-=D) 16 data[k]=data[k-D]; 17 data[k]=temp; 18 } 19 } 20 int main() 21 { 22 int N=0,flag=0; 23 cin>>N; 24 long int data[N]; 25 for(int i=0;i<N;i++) 26 cin>>data[i]; 27 shell_sort(data,N); 28 for(int i=0;i<N;i++) 29 if(flag++==0) 30 cout<<data[i]; 31 else 32 cout<<" "<<data[i]; 33 return 0; 34 }
测试结果
版权声明:本文为博主原创文章,未经博主允许不得转载。
四,堆排序(heap_sort)
1.堆排序(可改良)
利用堆来排序,关键是掌握如何把一个树调整成堆(下滤)
1 #include<iostream> 2 using namespace std; 3 int size,flag=0; 4 void PercDown(long int data[],int t,int N){ 5 int parent,child,temp; 6 temp=data[t]; 7 for(parent=t;parent*2+1<=N-1;parent=child){ 8 child=parent*2+1; 9 if(child!=N-1&&data[child+1]>data[child]) 10 child++; 11 if(data[child]>temp) data[parent]=data[child]; 12 else break; 13 } 14 data[parent]=temp; 15 } 16 void buildheap(long int data[],int N){ 17 for(int i=(N-2)/2;i>=0;i--) 18 PercDown(data,i,N); 19 } 20 int Delete(long int data[]){ 21 int temp=data[0]; 22 data[0]=data[size-1]; 23 size--; 24 PercDown(data,0,size); 25 26 return temp; 27 } 28 void heapsort(long int data[],int N){ 29 buildheap(data,N); 30 int temp[N]; 31 for(int i=N-1;i>=0;i--) 32 temp[i]=Delete(data); 33 for(int i=0;i<N;i++) 34 data[i]=temp[i]; 35 } 36 int main() 37 { 38 int N=0; 39 cin>>N; 40 size=N; 41 long int data[N]; 42 for(int i=0;i<N;i++) 43 cin>>data[i]; 44 heapsort(data,N); 45 for(int i=0;i<N;i++) 46 if(flag++==0) 47 cout<<data[i]; 48 else 49 cout<<" "<<data[i]; 50 return 0; 51 }
测试结果
2.改良的堆排序(排成最大堆,把根节点和末尾的节点交换,即最大的数跑去最后了,然后不再考虑那些已知位置排好的最大的了,在重复前面的步骤)
1 #include<iostream> 2 using namespace std; 3 int size,flag=0; 4 void PercDown(long int data[],int t,int N){ 5 int parent,child,temp; 6 temp=data[t]; 7 for(parent=t;parent*2+1<=N-1;parent=child){ 8 child=parent*2+1; 9 if(child!=N-1&&data[child+1]>data[child]) 10 child++; 11 if(data[child]>temp) data[parent]=data[child]; 12 else break; 13 } 14 data[parent]=temp; 15 } 16 void buildheap(long int data[],int N){ 17 for(int i=(N-2)/2;i>=0;i--) 18 PercDown(data,i,N); 19 } 20 int Delete(long int data[]){ 21 int temp=data[0]; 22 data[0]=data[size-1]; 23 size--; 24 PercDown(data,0,size); 25 26 return temp; 27 } 28 void heapsort2(long int data[],int N){ 29 buildheap(data,size); 30 for(int i=1;i<=N-1;i++){ 31 int temp=data[0]; 32 data[0]=data[size-1]; 33 data[--size]=temp; 34 PercDown(data,0,size); 35 } 36 } 37 int main() 38 { 39 int N=0; 40 cin>>N; 41 size=N; 42 long int data[N]; 43 for(int i=0;i<N;i++) 44 cin>>data[i]; 45 heapsort2(data,N); 46 for(int i=0;i<N;i++) 47 if(flag++==0) 48 cout<<data[i]; 49 else 50 cout<<" "<<data[i]; 51 return 0; 52 }
测试结果
版权声明:本文为博主原创文章,未经博主允许不得转载。
五,归并排序
1.递归方法的归并排序;
1 #include<iostream> 2 using namespace std; 3 int size,flag=0; 4 void Merge(long int data[],int l,int r,int rend,int temp[]){ 5 int n=rend-l+1; 6 int lend=r-1; 7 int s=l; 8 while(l<=lend&&r<=rend){ 9 if(data[l]<data[r]) temp[s++]=data[l++]; 10 else temp[s++]=data[r++]; 11 } 12 while(l<=lend) 13 temp[s++]=data[l++]; 14 while(r<=rend) 15 temp[s++]=data[r++]; 16 for(int i=0;i<n;i++) 17 data[rend]=temp[rend--]; 18 } 19 void Msort(long int data[],int l,int rend,int temp[]){ 20 int center; 21 if(l<rend){ 22 center=(l+rend)/2; 23 Msort(data,l,center,temp); 24 Msort(data,center+1,rend,temp); 25 Merge(data,l,center+1,rend,temp); 26 } 27 } 28 void Merge_sort(long int data[],int N){ 29 int *temp; 30 temp=(int*)malloc(N*sizeof(int)); 31 if(temp!=NULL){ 32 Msort(data,0,N-1,temp); 33 free(temp); 34 } 35 else 36 cout<<"these is no enough space"<<endl; 37 } 38 int main() 39 { 40 int N=0; 41 cin>>N; 42 size=N; 43 long int data[N]; 44 for(int i=0;i<N;i++) 45 cin>>data[i]; 46 Merge_sort(data,N); 47 for(int i=0;i<N;i++) 48 if(flag++==0) 49 cout<<data[i]; 50 else 51 cout<<" "<<data[i]; 52 return 0; 53 }
测试结果
2.非递归方法的归并排序
1 #include<iostream> 2 #include<memory> 3 using namespace std; 4 int size,flag=0; 5 void Merge1(long int data[],int l,int r,int rend,long int temp[]){ 6 int n=rend-l+1; 7 int lend=r-1; 8 int s=l; 9 while(l<=lend&&r<=rend){ 10 if(data[l]<data[r]) temp[s++]=data[l++]; 11 else temp[s++]=data[r++]; 12 } 13 while(l<=lend) 14 temp[s++]=data[l++]; 15 while(r<=rend) 16 temp[s++]=data[r++]; 17 //for(int i=0;i<n;i++) 18 //data[rend]=temp[rend--]; 19 } 20 void Merge_pass(long int data[],int N,long int temp[],int length){ 21 int i; 22 for(i=0;i<N-1-2*length;i+=length*2) 23 Merge1(data,i,i+length,i+2*length-1,temp); 24 if(i+length<N) 25 Merge1(data,i,i+length,N-1,temp); 26 else 27 for(int j=i;j<N;j++) temp[j]=data[j]; 28 29 } 30 void Merge_sort2(long int data[],int N){ 31 long int *temp; int length=1; 32 temp=(long int*)malloc(N*sizeof(long int)); 33 if(temp!=NULL){ 34 while(length<N){ 35 Merge_pass(data,N,temp,length); 36 length*=2; 37 Merge_pass(temp,N,data,length); 38 length*=2; 39 } 40 free(temp); 41 } 42 else 43 cout<<"there is no enough space"<<endl; 44 } 45 int main() 46 { 47 int N=0; 48 cin>>N; 49 size=N; 50 long int data[N]; 51 for(int i=0;i<N;i++) 52 cin>>data[i]; 53 Merge_sort2(data,N); 54 for(int i=0;i<N;i++) 55 if(flag++==0) 56 cout<<data[i]; 57 else 58 cout<<" "<<data[i]; 59 return 0; 60 }
测试结果
版权声明:本文为博主原创文章,未经博主允许不得转载。