各种排序算法总结
1、冒泡排序
/* 冒泡排序:将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡。 根据轻气泡不能在重气泡之下的原则,从下往上扫描数组 R:凡扫描到违反本原则的 轻气泡,就使其向上"飘浮"。如此反复进行,直到最后任何两个气泡都是轻者在上, 重者在下为止。 时间复杂度 o(n^2) 空间复杂度 o(1) 比较次数 n(n+1)/2 */ void bubble_sort(int a[],int len) { for(int i=0;i<len;i++) for(int j=len-1;j>i;j--) { if(a[j]<a[j-1]) { int tmp=a[j-1]; a[j-1]=a[j]; a[j]=tmp; } } }
发现我这么多年还是容易把冒泡排序弄混,注意冒泡是第二层倒着来,两两比较!常规排序两层都顺着来会导致第一次比较小的反而转到后面:
http://blog.csdn.net/cbs612537/article/details/8294960
2、直接插入排序
/* 直接插入排序 算法思想:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元 素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它 插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。 时间复杂度 o(n^2) 空间复杂度 o(1) 比较次数 n(n+1)/2 */ void insert_sort(int a[],int len) { int tmp,i,j; for( i=1;i<len;i++) { if(a[i]<a[i-1]) { tmp=a[i]; for(j=i-1;j>=0&&a[j]>tmp;j--) a[j+1]=a[j]; a[j+1]=tmp; } } }
3、希尔排序
/* 希尔排序 算法思想:先将整个待排序记录分割成若干子序列分别进行直接插入排 序,待整个序列中的记录基本有序时,再对全体记录进行一 次直接插入排序 时间复杂度 o(n^2) 空间复杂度 o(1) 比较次数 ?(最好n^1.3,一般nlogn,待解决) */ void shell_sort(int a[],int len) { int gap,i,j,tmp,k; for(gap=len/2;gap>0;gap/=2) for( i=0;i<gap;i++) { for(j=i+gap;j<len;j+=gap) { if(a[j]<a[j-gap]) { tmp=a[j]; k=j-gap; while(k>=0&&a[k]>tmp) { a[k+gap]=a[k]; k-=gap; } a[k+gap]=tmp; } } } }
4、直接选择排序
/* 直接选择排序 算法思想:直接选择排序和直接插入排序类似,都将数据分为有序区和无序区, 所不同的是直接播放排序是将无序区的第一个元素直接插入到有序区 以形成一个更大的有序区,而直接选择排序是从无序区选一个最小的元素 直接放到有序区的最后。每一趟在n-i+1个记录中选取关键字最小的记录作为有序序列中的第i个记录 时间复杂度 o(n^2) 空间复杂度 o(1) ? 比较次数 n(n+1)/2 */ void select_min_sort(int a[],int n) { int i,j,tmp; for(i=0;i<n;i++) { tmp=i; for(j=i+1;j<n;j++) if(a[tmp]>a[j]) tmp=j; int temp=a[i]; a[i]=a[tmp]; a[tmp]=temp; } }
5、快速排序
/* 快速排序 算法思想:先从数列中取出一个数作为基准数,分区过程,将比这个数大 的数全放到它的右边,小于或等于它的数全放到它的左边。 重复直到只有一个数,在对这数的两边分别进行快排。 递归地解这些子问题,然后将这些子问题的解组合成为原问题的解。 时间复杂度 o(nlogn) 空间复杂度 o(logn) 比较次数 ? */ void quick_sort(int a[],int low,int high) { if(low<high){ int privot=a[low]; int i=low,j=high; while(i<j) { while(a[j]>=privot&&j>i) j--; if(i<j) a[i++]=a[j]; while(a[i]<privot&&i<j) i++; if(i<j) a[j--]=a[i]; } a[i]=privot; quick_sort(a,low,i-1); quick_sort(a,i+1,high); } }
6、归并排序
/* 归并排序 算法思想:设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中。 时间复杂度 o(nlogn) 空间复杂度 o(n) 比较次数 ? */ void merge(int a[],int l,int mid,int h,int tep[]) { int i=l,j=mid; int m=mid+1,n=h; int k=0; while(i<=j&&m<=n) { if(a[i]<=a[m]) tep[k++]=a[i++]; else tep[k++]=a[m++]; } while(i<=j) tep[k++]=a[i++]; while(m<=n) tep[k++]=a[m++]; for( i=0;i<k;i++) a[l+i]=tep[i]; } void part(int a[],int l,int h,int tep[]) { if(l<h) { int mid=(l+h)/2; part(a,l,mid,tep); part(a,mid+1,h,tep); merge(a,l,mid,h,tep); } } void merge_sort(int a[],int n) { int *p=new int [n]; part(a,0,n-1,p); delete[] p; }
7、堆排序
/* 堆排序 算法思想:堆排序(Heap Sort)是指利用堆(heaps)这种数据结构来构造的一种排序算法。先建立大根堆,然后把最大数移到最后,缩小堆范围,直到满足堆里没数了 时间复杂度 o(nlogn) 空间复杂度 o(1) 比较次数:较多 */ void heap_adjust(int a[],int i,int n) { int root=a[i]; for(int j=2*i+1;j<n;j*=2+1) { if(j<n&& a[j]<a[j+1]) j++; if(root>=a[j]) break; a[i]=a[j]; i=j; } a[i]=root; } void heap_sort(int a[],int n) { int i; for(i=(n-1)/2;i>=0;i--) heap_adjust(a,i,n); for(i=n;i>0;i--) { int tmp=a[i]; a[i]=a[0]; a[0]=tmp; heap_adjust(a,0,i-1); } }