排序——归并排序(Merge Sort)及应用

蔚落 2022-08-20 12:09 300阅读 0赞

归并排序:是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

时间复杂度:O(nlgn)

空间复杂度:O(n)(用于存储有序子序列合并后有序序列)

稳定性:归并排序是稳定的排序

递归方法示意图(图来源网上)

Center

非递归方法示意图(图来源网上)

Center 1

实例:

  1. <pre name="code" class="cpp">//归并排序
  2. #include "stdafx.h"
  3. #include <iostream>
  4. using namespace std;
  5. //将有二个有序数列a[first...mid]和a[mid...last]合并。
  6. template<class T>
  7. void merge(T data[], int first, int mid, int last, T temp[])
  8. {
  9. int low1 = first, hight1 = mid;
  10. int low2 = mid + 1, hight2 = last;
  11. int k = first;
  12. while (low1 <= hight1 && low2 <= hight2)
  13. {
  14. if (data[low1] < data[low2])
  15. {
  16. temp[k++] = data[low1++];
  17. }
  18. else
  19. {
  20. temp[k++] = data[low2++];
  21. }
  22. }
  23. while (low1 <= hight1)
  24. {
  25. temp[k++] = data[low1++];
  26. }
  27. while (low2 <= hight2)
  28. {
  29. temp[k++] = data[low2++];
  30. }
  31. for (int i = first; i <= last; i++)
  32. {
  33. data[i] = temp[i];
  34. }
  35. }
  36. /*
  37. //递归
  38. template<class T>
  39. void mergesort(T data[], int first, int last, T temp[])
  40. {
  41. if (first < last)
  42. {
  43. int mid = (first + last) / 2;
  44. mergesort(data, first, mid, temp); //左边有序
  45. mergesort(data, mid + 1, last, temp); //右边有序
  46. merge(data, first, mid, last, temp); //再将二个有序数列合并
  47. }
  48. }
  49. */
  50. //非递归
  51. template<class T>
  52. void mergesort(T data[], int first, int last, T temp[])
  53. {
  54. int length = 1;
  55. int arrsize = last - first + 1;
  56. while (length <= arrsize)
  57. {
  58. for (int i = 0; i + 2 * length < arrsize; i += 2 * length)
  59. {
  60. int mid = (i + (i + 2 * length - 1)) / 2;
  61. merge(data, i, mid, i + 2 * length - 1, temp);
  62. }
  63. length *= 2;
  64. }
  65. }
  66. template<class T>
  67. bool MergeSort(T data[], int n)
  68. {
  69. T* temp = new T[n];
  70. if (NULL == temp)
  71. return false;
  72. mergesort(data, 0, n - 1, temp);
  73. delete[] temp;
  74. temp = NULL;
  75. return true;
  76. }
  77. template<class T>
  78. void Sprint(T data[], int n)
  79. {
  80. for (int i = 0; i < n; i++)
  81. {
  82. cout << data[i] << " ";
  83. }
  84. cout << endl;
  85. }
  86. int _tmain(int argc, _TCHAR* argv[])
  87. {
  88. int data[] = { 12, 0, 3, 5, 1, 4, 6, 2, 11 };
  89. int n = sizeof(data) / sizeof(int);
  90. MergeSort(data, n);
  91. Sprint(data, n);
  92. return 0;
  93. }

归并排序应用

题:在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序数对。一个排列中逆序的总数就称为这个排列的逆序数。如{2,4,3,1}中,2和1,4和3,4和1,3和1是逆序数对,因此整个数组的逆序数对个数为4,现在给定一数组,要求统计出该数组的逆序数对个数

代码实例

  1. #include "stdafx.h"
  2. #include <iostream>
  3. using namespace std;
  4. int g_nCount = 0;
  5. //将有二个有序数列a[first...mid]和a[mid...last]合并。
  6. template<class T>
  7. void merge(T data[], int first, int mid, int last, T temp[])
  8. {
  9. int low1 = first, hight1 = mid;
  10. int low2 = mid + 1, hight2 = last;
  11. int k = first;
  12. while (low1 <= hight1 && low2 <= hight2)
  13. {
  14. if (data[low1] < data[low2])
  15. {
  16. temp[k++] = data[low1++];
  17. }
  18. else
  19. {
  20. temp[k++] = data[low2++];
  21. g_nCount += hight1 - low1 + 1;
  22. }
  23. }
  24. while (low1 <= hight1)
  25. {
  26. temp[k++] = data[low1++];
  27. }
  28. while (low2 <= hight2)
  29. {
  30. temp[k++] = data[low2++];
  31. }
  32. for (int i = first; i <= last; i++)
  33. {
  34. data[i] = temp[i];
  35. }
  36. }
  37. //递归
  38. template<class T>
  39. void mergesort(T data[], int first, int last, T temp[])
  40. {
  41. if (first < last)
  42. {
  43. int mid = (first + last) / 2;
  44. mergesort(data, first, mid, temp); //左边有序
  45. mergesort(data, mid + 1, last, temp); //右边有序
  46. merge(data, first, mid, last, temp); //再将二个有序数列合并
  47. }
  48. }
  49. template<class T>
  50. bool MergeSort(T data[], int n)
  51. {
  52. T* temp = new T[n];
  53. if (NULL == temp)
  54. return false;
  55. mergesort(data, 0, n - 1, temp);
  56. delete[] temp;
  57. temp = NULL;
  58. return true;
  59. }
  60. template<class T>
  61. void Sprint(T data[], int n)
  62. {
  63. for (int i = 0; i < n; i++)
  64. {
  65. cout << data[i] << " ";
  66. }
  67. cout << endl;
  68. }
  69. int _tmain(int argc, _TCHAR* argv[])
  70. {
  71. int data[] = { 2, 4, 3, 1 };
  72. int n = sizeof(data) / sizeof(int);
  73. MergeSort(data, n);
  74. //Sprint(data, n);
  75. cout << g_nCount << endl;
  76. return 0;
  77. }

结果:

Center 2

发表评论

表情:
评论列表 (有 0 条评论,300人围观)

还没有评论,来说两句吧...

相关阅读

    相关 归并排序merge sort

    归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。(出自[维基百科][Li