C++排序算法之归并排序

阳光穿透心脏的1/2处 2022-06-12 02:42 306阅读 0赞

归并排序

(1)算法介绍

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用,归并排序将两个已经有序的序列合并成一个有序的序列。

思路:假设我们有一个没有排好序的序列,那么我们首先使用分割的方法将这个序列分割成一个个已经排好序的子序列(当一个序列只有一个元素时,该序列自然是有序的)。然后再利用归并的方法将一个个有序的子序列合并成排好序的序列。

2)算法执行过程

下面就一常用的二路归并排序讲解分割和合并的过程,看下图

待排序列为:14 12 15 13 11 16

Center

代码实现如下

  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. using namespace std;
  5. /*该函数将数组下标范围[l1,r1]和[l2,r2]的有序序列合并成一个有序序列*/
  6. void merge(vector<int>& nums, int l1, int r1, int l2, int r2 ) {
  7. int i = l1; //左半部分起始位置
  8. int j = l2; //右半部分起始位置
  9. int n = (r1 - l1 + 1) + (r2 - l2 + 1); //要合并的元素个数
  10. vector<int> temp(n); //辅助数组
  11. int k = 0; //辅助数组其起始位置
  12. while (i <= r1&&j <= r2) { //挑选两部分中最小的元素放入辅助数组中
  13. if (nums[i] < nums[j])
  14. temp[k++] = nums[i++];
  15. else
  16. temp[k++] = nums[j++];
  17. }
  18. //如果还有剩余,直接放入到辅助数组中
  19. while (i <= r1)
  20. temp[k++] = nums[i++];
  21. while (j <= r2)
  22. temp[k++] = nums[j++];
  23. //更新原始数组元素
  24. for (int i = 0; i < n;i++)
  25. {
  26. nums[l1 + i] = temp[i];
  27. }
  28. }
  29. /*二路归并排序(递归实现)*/
  30. void MergeSort(vector<int>& nums,int start, int end) {
  31. if (start < end) {
  32. int mid = (start + end) >> 1; //分割序列
  33. MergeSort(nums, start, mid); //对序列左半部分进行规并排序
  34. MergeSort(nums, mid + 1, end); //对序列右半部分进行规并排序
  35. merge(nums, start, mid, mid + 1, end); //合并已经有序的两个序列
  36. }
  37. }
  38. /*二路归并排序(迭代实现)*/
  39. void MergeSort1(vector<int>& nums, int start, int end)
  40. {
  41. int n = nums.size();
  42. if (start < end) {
  43. //step为组内元素个数,step/2为左子区间元素个数
  44. for (int step = 2; step/2 <n; step *= 2) {
  45. //每step个元素一组,组内前step/2和后step/2个元素进行合并
  46. for (int i = 0; i < n; i += step) {
  47. int mid = i + step / 2 - 1; //左子区间元素个数为step/2
  48. if(mid+1<n) //右子区间存在元素个数则合并
  49. //左子区间为[i,mid],右子区间为[mid+1, min(i+step-1, n-1)]
  50. merge(nums, i, mid, mid + 1, min(i + step - 1, n-1));
  51. }
  52. }
  53. }
  54. }
  55. int main() {
  56. vector<int> nums{ 1,4,3,2,5,6,3 };
  57. MergeSort(nums,0,6);
  58. // MergeSort1(nums, 0, 6);
  59. for (auto x : nums)
  60. cout << x << " ";
  61. cout << endl;
  62. return 0;
  63. }

运行结果如下

Center 1

复杂度分析

(1)时间复杂度

最坏情况=最好情况=平均情况=O(nlogn)

(2)空间复杂度

需要额外大小一样的辅助数组,因此空间复杂度为O(n)。

发表评论

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

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

相关阅读

    相关 排序算法归并排序

    归并排序是一种基于分治思想的排序算法,它的基本思路是将原始序列划分为若干个子序列,对每个子序列进行排序,然后将排好序的子序列合并为一个大序列,最终得到排序结果。具体来说,归并排

    相关 排序算法归并排序

    归并排序> 之前曾经实现过堆排序,它用到了完全二叉树,但是堆的设计本身就是比较复杂的,而今天要实现的归并排序同样的也用到了完全二叉树的思想,这种思想比堆排序较为简单.

    相关 排序算法归并排序

    归并排序是利用递归与分治思想将数据序列划分成越来越小的半子序列,在对其进行排序,最后利用递归将排好序的半子序列合并成越来越大的有序序列。 归并排序中,归 即是递归的意思,即递