1、一 插入排序1.1 直接插入排序基本思想:每次将一个待排序额记录按其关键码的大小插入到一个已经排好序的有序序列中,直到全部记录排好序。图解:代码实现:cpp view plain copy1. /直接顺序排序 2. void InsertSort(int r, int n) 3. 4. for (int i=2; i/希尔排序 2. void ShellSort(int r, int n) 3. 4. int i; 5. int d; 6. int j; 7. for (d=n/2; d=1; d=d/2) /以增量为 d 进行直接插入排序 8. 9. for (i=d+1; i0 5. in
2、t exchange; 6. int bound; 7. exchange=n-1; /第一趟起泡排序的范围是 r0到 rn-1 8. while (exchange) /仅当上一趟排序有记录交换才进行本趟排序 9. 10. bound=exchange; 11. exchange=0; 12. for (int j=0; jrj+1) 14. 15. temp=rj; 16. rj=rj+1; 17. rj+1=temp; 18. exchange=j; /记录每一次发生记录交换的位置 19. 20. 21. for(int i=0;i 2.2 快速排序基本思想:通过一趟排序将要排序的 数据
3、分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。图解:代码实现:cpp view plain copy1. /快速排序一次划分 2. int Partition(int r, int first, int end) 3. 4. int i=first; /初始化 5. int j=end; 6. int temp; 7. 8. while (irj) break; /根结点已经大于左右孩子中的较大者 15. else 16. 17. temp=ri; 18. ri=rj
4、; 19. rj=temp; /将根结点与结点 j 交换 20. i=j; 21. j=2*i+1; /被筛结点位于原来结点 j 的位置 22. 23. 24. 堆排序堆排序的基本思想是:首先将待排序的记录序列构造成一个堆,此时,选出了堆中所有记录的最大者即堆顶记录,然后将它从堆中移走(通常将堆顶记录和堆中最后一个记录交换),并将剩余的记录再调整成堆,这样又找出了次大的记录,以此类推,直到堆中只有一个记录为止。(1)用大根堆排序的基本思想 先将初始文件 R1n建成一个大根堆,此堆为初始的无序区 再将关键字最大的记录 R1(即堆顶)和无序区的最后一个记录 Rn交换,由此得到新的无序区 R1n-1
5、和有序区 Rn,且满足 R1n-1.keysRn.key由于交换后新的根 R1可能违反堆性质,故应将当前无序区 R1n-1调整为堆。然后再次将 R1n-1中关键字最大的记录 R1和该区间的最后一个记录 Rn-1交换,由此得到新的无序区 R1n-2和有序区 Rn-1n,且仍满足关系 R1n-2.keysRn-1n.keys,同样要将 R1n-2调整为堆。直到无序区只有一个元素为止。(2)大根堆排序算法的基本操作: 初始化操作:将 R1n构造为初始堆; 每一趟排序的基本操作:将当前无序区的堆顶记录 R1和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。注意:只需做 n-1 趟排序
6、,选出较大的 n-1 个关键字即可以使得文件递增有序。用小根堆排序与利用大根堆类似,只不过其排序结果是递减有序的。堆排序和直接选择排序相反:在任何时刻堆排序中无序区总是在有序区之前,且有序区是在原向量的尾部由后往前逐步扩大至整个向量为止代码实现:cpp view plain copy1. /堆排序 2. void HeapSort(int r , int n) 3. 4. 5. int i; 6. int temp; 7. for (i=n/2; i=0; i-) /初始建堆,从最后一个非终端结点至根结点 8. Sift(r, i, n) ; 9. for (i=n-1; i0; i-) /重
7、复执行移走堆顶及重建堆的操作 10. 11. temp=ri; 12. ri=r0; 13. r0=temp; 14. Sift(r, 0, i-1); 15. 16. for(i=0;in;i+) 17. coutri“ “; 18. cout“n“; 19. 四 归并排序二路归并排序基本思想:将若干个有序序列进行两两归并,直至所有待排序记录都在一个有序序列为止。一路归并算法实现:cpp view plain copy1. /一次归并 2. void Merge(int r, int r1, int s, int m, int t) 3. 4. 5. int i=s; 6. int j=m+
8、1; 7. int k=s; 8. 9. while (i=m /取 ri和 rj中较小者放入 r1k 13. else 14. r1k+=rj+; 15. 16. if (i=m) 17. while (i=m) /若第一个子序列没处理完,则进行收尾处理 18. r1k+=ri+; 19. else 20. while (j=t) /若第二个子序列没处理完,则进行收尾处理 21. r1k+=rj+; 22. cpp view plain copy1. /一趟归并 2. void MergePass(int r , int r1 , int n, int h) 3. 4. int i=0; 5
9、. int k; 6. 7. while (i=n-2*h) /待归并记录至少有两个长度为 h 的子序列 8. 9. Merge(r, r1, i, i+h-1, i+2*h-1); 10. i+=2*h; 11. 12. if (in-h) 13. Merge(r, r1, i, i+h-1, n); /待归并序列中有一个长度小于 h 14. else for (k=i; k=n; k+) /待归并序列中只剩一个子序列 15. r1k=rk; 16. 17. 18. /归并排序的非递归算法 19. void MergeSort1(int r , int r1 , int n ) 20. 21
10、. int h=1; 22. int i; 23. 24. while (hn) 25. 26. MergePass(r, r1, n-1, h); /归并 27. h=2*h; 28. MergePass(r1, r, n-1, h); 29. h=2*h; 30. 31. for(i=0;in;i+) 32. coutri“ “; 33. cout“n“; 34. 下面看看二路归并排序的递归实现cpp view plain copy1. /归并排序的递归算法 2. void MergeSort2(int r, int r1, int r2,int s, int t) 3. 4. 5. int m; 6. if (s=t) 7. 8. r1s=rs; 9. 10. 11. else 12. 13. m=(s+t)/2; 14. MergeSort2(r, r2, r1, s, m); /归并排序前半个子序列15. MergeSort2(r, r2, r1, m+1, t); /归并排序后半个子序列 16. Merge(r2, r1, s, m, t); /将两个已排序的子序列归并17. 18. 总结各种排序方法的比较(未完待续):