排序算法汇总 c++
2017-08-08 15:24
225 查看
#include <stdlib.h> #include <stdio.h> #include <vector> #include <iostream> using namespace std; template<typename T> void v_print( vector<T>& v){ int v1(v.size()); for(int k1(0);k1<v1;++k1) cout<<v[k1]<<" "; cout<<endl; } /*冒泡排序:依次比较相邻的数据,小数据放前,大数据放后。 第一趟将最大数滚到最后一个位置,第二趟将次大的数滚到倒数第二个位置,...,依次将“最大数”的滚动到“最后”,共需要n-1趟。 时间复杂度O(n^2),空间复杂度为O(1)。 稳定排序,元素较少时效率较高。*/ template<typename T> void bubbleSort1( vector<T>& v){ int v1(v.size()); for(int k1(0);k1<v1-1;++k1){ for(int k2(0);k2<v1-1-k1;++k2){ if(v[k2+1]<v[k2])swap(v[k2+1],v[k2]); //v_print(v); } } } /*冒泡排序优化:设置一个标志,如果第一次比较完没有交换,即说明已经有序,不应该进行下一次遍历,还有已经遍历出部分有序的序列后, 那部分也不用进行遍历。 最坏情况,反序序列,时间复杂度O(n^2);最好情况,正序,时间复杂度O(n)。*/ template<typename T> void bubbleSort2( vector<T>& v ){ int v1(v.size()); bool flag(1); //cout<<v1<<endl; for(int k1(0);k1<v1-1&&flag;++k1){ flag=false; for(int k2(0);k2<v1-1-k1;++k2){ if(v[k2+1]<v[k2])swap(v[k2+1],v[k2]),flag=true; //v_print(v); } } } /*选择排序:正序,第一趟遍历N个数据,找到最小的数值与第一个元素交换,第二趟遍历剩下N-1个元素,找出其中最小的数值与第二元素交换... 与冒泡的查找过程一样,但是选择排序每一趟只最后交换一次,因此选择排序的效率相较于冒泡只高不低。 时间复杂度O(n^2),空间复杂度为O(1)。*/ template<typename T> void selectSort( vector<T>& v){ int v1(v.size()); for(int k1(0),km(0);k1<v1-1;++k1,km=k1){ for(int k2(k1+1);k2<v1;++k2){ if(v[k2]<v[km])km=k2; } swap(v[km],v[k1]); //v_print(v); } } /*插入排序:与扑克摸牌一样。插入即表示将一个新数据插入到一个有序数组中,并保持有序。 时间复杂度:最好的情况O(n);最坏的情况O(n^2)。空间复杂度O(1)。 稳定排序,元素少是效率好。*/ template<typename T> void insertSort( vector<T>& v){ int v1(v.size()); for(int k1(1),k2,tem;k1<v1;++k1){ for(tem=v[k1],k2=k1;0<k2 && tem<v[k2-1];--k2){ v[k2] = v[k2-1]; //v_print(v); } v[k2] = tem; //v_print(v); } } /*希尔排序:按照不同步长对元素进行插入排序,步长逐步递减直到为1。又称为缩小增量排序。 时间复杂度依赖于增量序列,平均O(nlogn),最差O(n^2) 不稳定排序,空间复杂度O(1)。*/ template<typename T> void shellSort( vector<T>& v){ int v1(v.size()); for(int kd(v1/2);kd;kd>>=1){ for(int k1(0);k1<kd;++k1){ for(int k2(k1+kd);k2<v1;k2+=kd){ for(int k3(k2);k1<k3;k3-=kd){ if(v[k3]<v[k3-kd]) swap(v[k3],v[k3-kd]); /*else v_print(v);*/ } } } } } template<typename T> void shellSort1( vector<T>& v){ int t=0; int v1(v.size()); T tem; for(int kd=(v1/2);kd>0;kd>>=1){ for(int k1(kd),k2;k1<v1;k1+=kd){ for(k2=k1,tem=v[k1];k2>0&&tem<v[k2-kd];k2-=kd){ v[k2]=v[k2-kd]; //v_print(v); } v[k2]=tem; //v_print(v);t++; } } cout<<"t="<<t<<endl; } /*归并排序:先递归地将序列分为短序列,递归出口为短序列只有一个元素,然后把各个有序的短序列合并为一个有序序列。 时间复杂度:O(nlogn),稳定,适合元素较多的情况。*/ template<typename T> void mergearray(vector<T>& a,int first,int mid,int last,vector<T>& temp) { int i=first,j=mid+1; int n=mid,m=last; int k=0; while( i<=n && j<=m ) { if(a[i]<a[j]) temp[k++]=a[i++]; else temp[k++]=a[j++]; } while(i<=n) temp[k++]=a[i++]; while(j<=m) temp[k++]=a[j++]; for(i=0;i<k;i++) a[first+i] = temp[i]; } template<typename T> void merge(vector<T>& a,int first,int last,vector<T>& temp){ if(first<last) { int mid = (first+last)/2; merge(a,first,mid,temp); merge(a,mid+1,last,temp); mergearray(a,first,mid,last,temp); } } template<typename T> void mergeSort( vector<T>& v){ int v1(v.size()); vector<T> p(v1); merge(v,0,v1-1,p); } /*快速排序:划分交换排序,采用分治策略。先从数列末尾取一个元素作为基准元;然后将小于它的元素放在左边,不小于的放在右边;然后再对左右区间重复第二步,直至只要一个元素。 时间复杂度的最好情况和平均情况一样为O(nlogn),最坏情况下为O(n^2 )。空间复杂度为O(1)。 不稳定排序。*/ template<typename T> int partition( vector<T>& v,int first,int last ){ int kt(first); for(int k1(first);k1<last;++k1){ if(v[k1]<v[last]){ swap(v[kt++],v[k1]); //v_print(v); } } swap(v[kt],v[last]); //v_print(v); return kt; } template<typename T> void quickSort( vector<T>& v,int first,int last){ if(first<last) { int pivot = partition(v,first,last); quickSort(v,first,pivot-1); quickSort(v,pivot+1,last); //v_print(v); } } template<typename T> void quickSort( vector<T>& v ){quickSort(v,0,v.size()-1);} /*堆排序:初始化堆;将当前无序去的堆顶元素通该区域最后一个元素交换,然后调整堆,即将堆顶元素“下沉”到正确的位置。 时间复杂度:最好,最坏都是O(nlogn),较多元素的时候效率比较高,空间复杂度为O(1)。 不稳定排序。*/ template<typename T> void minheapfixdown( vector<T>& v,int i, int n){ T temp=v[i]; int j=2*i+1; while(j<n) { if( j+1<n && v[j+1]<v[j] ) j++; if(v[j] >= temp) break; v[i]=v[j]; i=j; j=i*2+1; } v[i] = temp; } template<typename T> void maxheapfixdown( vector<T>& v,int i, int n){ T temp=v[i]; int j=2*i+1; while(j<n) { if( j+1<n && v[j+1]>v[j] ) j++; if(v[j] <= temp) break; v[i]=v[j]; i=j; j=i*2+1; } v[i] = temp; } template<typename T> void buildheap( vector<T>& v,int v1){ for(int k1(v1/2-1);k1>=0;k1--)maxheapfixdown(v,k1,v1); } template<typename T> void heapSort( vector<T>& v ){ int v1(v.size()); buildheap(v,v1); for(int k1(v1-1);k1>0;--k1){ swap(v[k1],v[0]); maxheapfixdown(v,0,k1); } } void main() { int num[]={2,5,6,8,4,3,9,1,0,7}; vector<int> v(num,num+10);//vs2010没办法不支持C++11/(ㄒoㄒ)/ string str[]={"a","is","the","first","word"}; vector<string> s(str,str+5); cout<<"before:"<<endl; v_print(v); //bubbleSort1(v); bubbleSort2(v); //insertSort(v); //selectSort(v); //shellSort(v); //shellSort1(v); //mergeSort(v); //quickSort(v); //heapSort(v); cout<<"after:"<<endl; v_print(v); }