[关闭]
@CrazyHenry 2018-03-13T11:36:25.000000Z 字数 2299 阅读 905

0.x 9.归并排序

dddd数据结构课本


自顶向下

  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <iterator>
  5. #include <algorithm>
  6. #include <typeinfo>
  7. #include <numeric>
  8. #include <memory>
  9. #include <stdexcept>
  10. #include <fstream>
  11. #include <sstream>
  12. using namespace std;
  13. //win+<-/-> 切换窗口位置
  14. //ctrl+win+<-/->切换桌面
  15. //ctrl+alt+上/下 改变显示器方向
  16. template<typename T>
  17. void __merge(T arr[], int l, int mid, int r){
  18. //* VS不支持动态长度数组, 即不能使用 T aux[r-l]的方式申请aux的空间
  19. //* 使用VS的同学, 请使用new的方式申请aux空间
  20. //* 使用new申请空间, 不要忘了在__merge函数的最后, delete掉申请的空间:)
  21. //T aux[r-l];
  22. T *aux = new T[r-l];
  23. for( int i = l ; i != r; ++i ) //采用C++11的循环风格
  24. aux[i-l] = arr[i];
  25. // 初始化,i指向左半部分的起始索引位置l;j指向右半部分起始索引位置mid
  26. int i = l, j = mid;
  27. for( int k = l ; k != r; ++k ){
  28. if( i == mid ){ // 如果左半部分元素已经全部处理完毕
  29. arr[k] = aux[j-l]; ++j;
  30. }
  31. else if( j == r ){ // 如果右半部分元素已经全部处理完毕
  32. arr[k] = aux[i-l]; ++i;
  33. }
  34. else if( aux[i-l] <= aux[j-l] ) { // 左半部分所指元素 <= 右半部分所指元素,稳定排序
  35. arr[k] = aux[i-l]; ++i;
  36. }
  37. else{ // 左半部分所指元素 > 右半部分所指元素
  38. arr[k] = aux[j-l]; ++j;
  39. }
  40. }
  41. delete[] aux;
  42. }
  43. // 递归使用归并排序,对arr[l...r)的范围进行排序
  44. template<typename T>
  45. void __mergeSort(T arr[], int l, int r){
  46. int mid = l + (r-l)/2;//注意,这里处理得很细腻了
  47. if( l == mid )//注意,当r-l<=20,可以使用插入排序更快
  48. return;
  49. __mergeSort(arr, l, mid);
  50. __mergeSort(arr, mid, r);
  51. if(arr[mid - 1] > arr[mid])
  52. __merge(arr, l, mid, r);
  53. }
  54. template<typename T>
  55. void mergeSort(T arr[], int n){
  56. __mergeSort( arr , 0 , n );
  57. }
  58. int main() {
  59. int a[20] = {10,9,8,7,6,5,4,3,2,1,10,9,8,7,6,5,4,3,2,1};
  60. mergeSort(a,20);
  61. for( int i = 0 ; i < 20 ; i ++ )
  62. cout<<a[i]<<ends;
  63. cout<<endl;
  64. return 0;
  65. }

自底向上

  1. template<typename T>
  2. void __merge(T arr[], int l, int mid, int r){ //只有1个也可以merge
  3. //* VS不支持动态长度数组, 即不能使用 T aux[r-l]的方式申请aux的空间
  4. //* 使用VS的同学, 请使用new的方式申请aux空间
  5. //* 使用new申请空间, 不要忘了在__merge函数的最后, delete掉申请的空间:)
  6. //T aux[r-l];
  7. T *aux = new T[r-l];
  8. for( int i = l ; i != r; ++i )
  9. aux[i-l] = arr[i];
  10. // 初始化,i指向左半部分的起始索引位置l;j指向右半部分起始索引位置mid
  11. int i = l, j = mid;
  12. for( int k = l ; k != r; ++k ){
  13. if( i == mid ){ // 如果左半部分元素已经全部处理完毕
  14. arr[k] = aux[j-l]; ++j;
  15. }
  16. else if( j == r ){ // 如果右半部分元素已经全部处理完毕
  17. arr[k] = aux[i-l]; ++i;
  18. }
  19. else if( aux[i-l] <= aux[j-l] ) { // 左半部分所指元素 <= 右半部分所指元素,稳定排序
  20. arr[k] = aux[i-l]; ++i;
  21. }
  22. else{ // 左半部分所指元素 > 右半部分所指元素
  23. arr[k] = aux[j-l]; ++j;
  24. }
  25. }
  26. delete[] aux;
  27. }
  28. template<typename T>
  29. void mergeSort(T arr[], int n){
  30. for(int sz = 1; sz < n; sz+=sz) //sz<n即可,不必<=
  31. for(int i = 0; i +sz < n; i += sz + sz)//sz+i<n即可,不必<=
  32. __merge(arr, i, i+sz, min(i +sz + sz, n));
  33. }
  34. int main() {
  35. int a[20] = {10,9,8,7,6,5,4,3,2,1,10,9,8,7,6,5,4,3,2,1};
  36. mergeSort(a,20);
  37. for( int i = 0 ; i < 20 ; i ++ )
  38. cout<<a[i]<<ends;
  39. cout<<endl;
  40. return 0;
  41. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注