归并排序

33 阅读1分钟

说明

采用分治思想, 先进行序列划分,再进行元素的有序合并

时间空间复杂度

排序算法平均时间复杂度最好时间复杂度最坏时间复杂度空间复杂度稳定性
归并排序O(nlog2nn\log_{2}{n})O(nlog2nn\log_{2}{n})O(nlog2nn\log_{2}{n})O(n)稳定

代码

#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

// 归并过程函数
void Merge(int arr[], int l, int m, int r) {

  // 开辟额外的空间,将两个小段有序的序列合并成大段有序的序列
  int* p = new int[r - l + 1];
  int idx = 0;  // 数组的下标

  int i = l;  // 左边序列的首元素
  int j = m + 1;  // 右边元素的首元素

  while (i <= m && j <= r) {

    if (arr[i] <= arr[j]) {

      p[idx++] = arr[i++];
    } else {
      p[idx++] = arr[j++];
    }

  }

  // 左边的小段还有剩余
  while (i <= m) {
    p[idx++] = arr[i++];
  }

  // 右边的小段还有剩余
  while (j <= r) {
    p[idx++] = arr[j++];
  }


  // 再把合并好的大段有序的结果拷贝到原始arr数组的[l, r]区间内
  for (i = l, j = 0; i <= r; i++, j++) {
    arr[i] = p[j];
  }

  // 释放内存
  delete []p;

}

// 归并排序递归接口

void MergeSort(int arr[], int begin, int end) {
  // 递归结束的条件
  if (begin >= end) {
    return;
  }

  int mid = (begin + end) / 2;

  // 先递
  MergeSort(arr, begin, mid);
  MergeSort(arr, mid + 1, end);

  // 再归并.   [begin, mid], [mid + 1, end]将两个小段有序的序列合并成大段有序的序列
  Merge(arr, begin, mid, end);


}

void MergeSort(int arr[], int size) {
  MergeSort(arr, 0, size - 1);
}

int main() {

  int arr[10];
  srand(time(nullptr));

  for (int i = 0; i < 10; i++) {
    arr[i] = rand() % 100 + 1;
  }

  for (int v : arr) {
    cout << v << " ";
  }

  cout << endl;

  MergeSort(arr, 10);

  for (int v : arr) {
    cout << v << " ";
  }

  cout << endl;

  return 0;
}

测试

➜  build git:(main) ✗ ./MergeSort    
65 70 37 37 19 23 70 86 89 45 
19 23 37 37 45 65 70 70 86 89