#define SUM 100 #include <iostream> #include <vector> #include <string> #include <ctime> using namespace std; void InsertSort(int A[],int n){ int j; for(int i=2;i<=n;i++){ if(A[i]<A[i-1]){ A[0]=A[i]; for(j=i-1;A[j]>A[0];j--){ A[j+1]=A[j]; } A[j]=A[0]; } } cout<<"直接插入"<<endl; for(int k=1;k<=n;k++){ printf("%-5d ",A[k]); if(k!=0&&k%9==0) cout<<" "; } } void BinaryInsertSort(int A[],int n){ int j; for(int i=2;i<=n;i++){ if(A[i]<A[i-1]){ A[0]=A[i]; int low=1,high=i-1; while(low<=high){ int mid=(low+high)/2; if(A[mid]>A[0]){ high=mid-1; }else low=mid+1; } for(j=i-1;j>=high+1;j--){ A[j+1]=A[j]; } A[high+1]=A[0]; } } cout<<endl<<"折半插入"<<endl; for(int k=1;k<=n;k++){ printf("%-5d ",A[k]); if(k!=0&&k%9==0) cout<<" "; } } void ShellSort(int A[],int n){ int j; for(int dk=n/2;dk>=1;dk=dk/2){ for(int i=dk+1;i<=n;i++){ if(A[i]<A[i-dk]){ A[0]=A[i]; for(j=i-dk;j>0&&A[0]<A[j];j-=dk) A[j+dk]=A[j]; A[j+dk]=A[0]; } } } //选定相隔dk的两个元素进行比较,例如将1和51比较,2和52比较。。。 //以此类推之后将步长缩短一半,例如将1和26比较,2和27比较。。。 //到步长为1的时候序列基本有序,加少了移动的步骤 cout<<endl<<"希尔排序"<<endl; for(int k=1;k<=n;k++){ printf("%-5d ",A[k]); if(k!=0&&k%9==0) cout<<" "; } } void BubbleSort(int A[],int n){ int temp; for(int i=n;i>=0;i--){//此处之所以是i=n是为了照顾之前的A[0]处为哨兵的设置 for(int j=i-1;j>=0;j--){ if(A[i]<A[j]){ temp=A[i]; A[i]=A[j]; A[j]=temp; } } } cout<<endl<<"冒泡排序"<<endl; for(int k=1;k<=n;k++){ printf("%-5d ",A[k]); if(k!=0&&k%9==0) cout<<" "; } } void produceRandomNumbers(int A[],const int start, const int end, const int amount) { srand((unsigned)time(NULL)); for (int cnt = 1; cnt <= amount; ++cnt) { A[cnt]=start + (rand() % (end - start)); } } int Partition(int A[],int low,int high){ int pivot=A[low]; while(low<high){ while(low<high&&A[high]>=pivot) --high; A[low]=A[high]; while(low<high&&A[low]<=pivot) ++low; A[high]=A[low]; } A[high]=pivot;//此时high=low,指向的位置就是pivot应该在的位置 return low; } /* 在执行过程中有两个指针分别是low和high, 和一个临时变量pivot用来记录当前排序的元素(就是在本次排序的目的就是将pivot插入到准确位置) 在开始执行时将pivot设置为A[low],然后从high到low之间遍历,如果发现有逆序元素就移到low上 再从low到high之间遍历,如果发现有逆序元素就移到high上 有点像将一个乱序表的第一个元素所在的位置清零,如果从high到low中发现逆序就将该逆序元素填到坑里 此时坑在较高位置 然后从low到high,如果发现逆序元素就把该元素填到坑里,该元素原本的位置即为坑,此时坑在较低位置 知道low=high时,此时low的位置就是pivot应该在的位置。一次排序结束。递归分段继续 */ void QuickSort(int A[],int low,int high){ if(low<high){ int pivotpos=Partition(A,low,high); QuickSort(A,low,pivotpos-1); QuickSort(A,pivotpos+1,high); } } int main(){ int A[SUM+1];//因为A[0]存放哨兵 produceRandomNumbers(A,1, 10000, SUM); InsertSort(A,SUM); produceRandomNumbers(A,1, 10000, SUM); BinaryInsertSort(A,SUM); produceRandomNumbers(A,1, 10000, SUM); ShellSort(A,SUM); produceRandomNumbers(A,1, 10000, SUM); BubbleSort(A,SUM); produceRandomNumbers(A,1, 10000, SUM); QuickSort(A,0,SUM); cout<<endl<<"快速排序"<<endl; for(int k=1;k<=SUM;k++){ printf("%-5d ",A[k]); if(k!=0&&k%9==0) cout<<" "; } return 0; }