归并排序(mege sort)

发布时间 2023-09-08 13:47:21作者: 悉野
参考: https://www.cnblogs.com/kite97/p/13441391.html
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <chrono>
using namespace std;
using namespace chrono;

void Swap(int* arr, int idxA, int idxB)
{
    int tmp = arr[idxA];
    arr[idxA] = arr[idxB];
    arr[idxB] = tmp;
}

void MergeData(int* arr, int start, int mid, int end, int* tmp)
{
    //从start到mid是有序的(左边列表), 从mid到end也是有序的(右边列表)
    // 如 左边列表:[2, 5, 6, 7] 右边列表[1, 3, 5, 6]
    // 两边列表都从左向取值, 边取边比较
    // 申请一个临时空间来放数据
    int total = end - start;
    int left = start;
    int right = mid;
    for (int i = 0; i < total; ++i)
    {
        if (left >= mid && right < end)
        {
            //左边列表已经用完了, 放右边的
            tmp[i] = arr[right++];
        }
        else if (right >= end && left < mid)
        {
            //右边用完了, 左边还有
            tmp[i] = arr[left++];
        }
        else if (arr[left] < arr[right])
        {
            tmp[i] = arr[left++];
        }
        else
        {
            tmp[i] = arr[right++];
        }
    }
    //tmp里面的值复制到原arr中
    memcpy(&arr[start], tmp, sizeof(int) * total);
}

// 不含end
void MergeSort(int* arr, int start, int end, int* tmpArr)
{
    int len = end - start;
    if (len <= 1)
    {
        return;
    }
    else if (len == 2)
    {
        if (arr[start] > arr[start + 1])
        {
            Swap(arr, start, start + 1);
        }
        return;
    }
    int midLen = len >> 1;
    int mid = start + midLen;

   // cout << "start:" << start << ",end:" << end << endl;

    MergeSort(arr, start, mid, tmpArr);
    MergeSort(arr, mid, end, tmpArr);
    //合并
    MergeData(arr, start, mid, end, tmpArr);
}

int main()
{
    int maxSize = 50;
    srand(time(NULL));
    int* arr = new int[maxSize];
    cout << "data:\n";
    
    for (int i = 0; i < maxSize; ++i)
    {
        arr[i] = rand() % 100;
        cout << arr[i] << " ";
    }
    cout << "\nsorted data:" << endl;
    auto start = system_clock::now();
    auto startTick = duration_cast<chrono::milliseconds>(start.time_since_epoch()).count();
    int* tmpArr = new int[maxSize];
    MergeSort(arr, 0, maxSize, tmpArr);
    for (int i = 0; i < maxSize; ++i)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
    auto endTick = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
    auto useTick = endTick - startTick;
    cout << "Use Time:" << useTick << flush;
    delete[] tmpArr;
    delete[] arr;
    system("pause");
    return 0;
}