常用排序算法
如题:第一行输入一个数n,为整数个数。第二行有n个数,每个数都不超过int类型。
输出升序排序后的数,以空格隔开。
1.冒泡排序
两两比较,如果不满足条件则交换位置。
1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 6 int a[100005]; 7 8 int main() 9 { 10 int n; 11 scanf("%d",&n); 12 for(int i=0;i<n;i++){ 13 scanf("%d",&a[i]); 14 } 15 for(int i=0;i<n-1;i++){ 16 for(int j=0;j<n-1-i;j++){ 17 if(a[j]>a[j+1]){ 18 int temp=a[j]; 19 a[j]=a[j+1]; 20 a[j+1]=temp; 21 } 22 } 23 } 24 for(int i=0;i<n;i++){ 25 printf("%d ",a[i]); 26 } 27 return 0; 28 }
2.优化的冒泡排序
第一步优化:如果里面一层循环在某次扫描中没有执行交换,则说明此时数组已经全部有序列,无需再扫描了。因此,增加一个标记,每次发生交换,就标记,如果某次循环完没有标记,则说明已经完成排序。
void each(int *a,int *b){ int temp=*a; *a=*b; *b=temp; } //第一步优化冒泡排序 void bubble_sort(int a[],int n){ bool b=false; for(int i=0;i<n-1&&b==false;i++){ b=true; for(int j=n-1;j>i;j--){ if(a[j-1]>a[j]){ each(&a[j-1],&a[j]); b=false; } } } }
第二步优化:在第一步的基础上思考,既然可以记录序列是否已经有序,那么当无序的时候,是否可以记录里面有序的部分呢。
看第一步优化后的代码,每次内循环之前,前i项是有序的。当进行内循环时,如果最后一次进行交换的下标是lasttemp,那么不就说明从i到lasttemp都没有再进行交换,就说明i到lasttemp这一段也是有序的,那么前lasttemp说明也是有序的。下一次内循环之前,就不用再从n-1到i了,从n-1到lasttemp即可。
void each(int *a,int *b){ int temp=*a; *a=*b; *b=temp; } //第二步优化冒泡排序 void bubble_sort(int a[],int n){ int lasttemp; for(int i=0;i<n-1;i++){ lasttemp=n-1; for(int j=n-1;j>i;j--){ if(a[j-1]>a[j]){ each(&a[j-1],&a[j]); lasttemp=j; } } i=lasttemp-1;//因为下一步是i++,所以先-1. } }
3.选择排序
每遍历一次找出最大的元素,放无序序列的最后一位。
#include <iostream> #include <cstdio> using namespace std; int a[100005]; int main() { int n; int maxx;//每次存储最大数的下标 scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&a[i]); } //选择排序 for(int i=n-1;i>=0;i--){ maxx=0; for(int j=0;j<=i;j++){ if(a[maxx]<a[j]){ maxx=j; } } int temp=a[maxx]; a[maxx]=a[i]; a[i]=temp; } for(int i=0;i<n;i++){ printf("%d ",a[i]); } return 0; }
4.插入排序
void each(int *a,int *b){ int temp=*a; *a=*b; *b=temp; } //插入排序 void insertion_sort(int a[],int n){ for(int i=1;i<n;i++){ for(int j=i;j>=1;j--){ if(a[j]<a[j-1]){ each(&a[j],&a[j-1]); continue; } break; } } }
5.改进的插入排序
插入排序本来是一个一个地比较,然后找到最终的插入位置,但是这个查找位置过程可以用二分查找法代替,找到插入位置后,把它往后的元素全部往后平移一位,再将第i个数插入进去。当有100000个元素时,可以将比较次数减少到20以内。
int a[100005];//全局数组 int binarysearch(int en,int num){ int st=0; if(num<=a[st]){ return 0; } if(num>=a[en]){ return en+1; } while(st+1!=en){ int mid=(st+en)/2; if(num==a[mid]){ return mid; } if(num<a[mid]){ en=mid; } if(num>a[mid]){ st=mid; } } return en; } //插入排序 void insertion_sort(int n){ for(int i=1;i<n;i++){ int en=binarysearch(i-1,a[i]); if(en==i){ continue; }else{ int t=a[i]; for(int j=i;j>en;j--){ a[j]=a[j-1]; } a[en]=t; } } }
持续更新ing~~