排序之归并排序--C++

22 阅读1分钟

分治算法

通过将一个问题分解为几个小的、相似的子问题,递归解决这些子问题,然后将子问题的解合并以解决原始问题。

分治法步骤

  1. 分解(Divide) :将原问题分解为若干个规模较小但类似于原问题的子问题。
  2. 解决(Conquer) :递归解决这些子问题。如果子问题足够小,可以直接解决而不需要进一步分解。
  3. 合并(Combine) :将子问题的解合并为原问题的解。

归并排序

image.png

步骤一: 首先将待排序的元素分成大小大致相同的两个序列。

步骤二: 再把子序列分成大小大致相同的两个子序列。

步骤三: 如此下去,直到分解成一个元素停止,这时含有一个元素的子序列都是有序的。

步骤四: 进行合并操作,将两个有序的子序列合并为一个有序序列,如此下去,直到所有的元素都合并为一个有序序列。

代码详解

#include <iostream>
#include <vector>
using namespace std;

void merge(int arr[], int front, int mid, int rear){
    int temp[rear - front + 1];
    int i = front, j = mid + 1, k = 0;
    while(i <= mid && j <= rear){
        if(arr[i] < arr[j]){
            temp[k++] = arr[i++];
        } else {
            temp[k++] = arr[j++];
        }
    }
    while(i <= mid){
        temp[k++] = arr[i++];
    }
    while(j <= rear){
        temp[k++] = arr[j++];
    }
    for(int e = 0; e < k; e++){
        arr[front + e] = temp[e];
    }
}

void mergesort(int arr[], int front, int rear){
    if(rear > front){
        int mid = (front + rear) / 2;
        mergesort(arr, front, mid);
        mergesort(arr, mid + 1, rear);
        merge(arr, front, mid, rear);
    }
}

int main(){
    int n;
    cin >> n;
    int arr[n];
    for(int i = 0; i < n; i++){
        cin >> arr[i];
    }
    cout << endl;
    mergesort(arr, 0, n - 1);
    cout << "排序后:" << endl;
    for(int i = 0; i < n; i++){
        cout << arr[i] << " ";
    }
    cout << endl;
    return 0;
}