zoukankan      html  css  js  c++  java
  • 二路归并排序C++ 递归实现

    归并排序

    归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer) 的一个典型的应用。
    将已有序的字序列合并,得到完全有序的序列;即先使得每个字序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,成为2-路归并排序。
    算法描述:
    1、把长度为n的输入序列分成两个长度为n/2的字序列;
    2、对这两个子序列分别采用归并排序
    3、将两个排序好的字序列合并成一个最终的排序序列。

    优劣分析:

    归并排序是一种稳定的排序算法。和选择排序一样,归并排序性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(nlogn)的时间复杂度。
    代价是需要额外的内存空间。

    1、 归并排序采用了分治的思想,它的核心在于合并子问题而不是求解子问题。【快速排序也采用了分治思想,但它的核心是在于求解子问题而不需要合并子问题的解】
    2、归并排序不是原地址排序,它的排序过程需要借助额外的内存空间。
    3、归并排序是稳定排序(其实,还要看具体代码怎么写,如果两个数的值相等,不保持原顺序就会变成非稳定的了)
    4、归并排序的时间复杂度为O(NlogN)

    /* MergeSort_hpp */
    #ifndef MergeSort_hpp
    #define MergeSort_hpp
    
    #include <stdio.h>
    #include <vector>
    using namespace std;
    
    class MergeSort {
    public:
        void sort(vector<int>& arr, int len);
    };
    
    #endif /* MergeSort_hpp */
    
    
    #include "MergeSort.hpp"
    void subSort(vector<int>& arr, int left, int right, vector<int>& temp);
    void merge(vector<int>& arr, int left, int mid, int right, vector<int>& temp);
    
    void MergeSort::sort(vector<int>& arr, int len) {
        if (len < 2) {
            return;
        }
        vector<int> temp(arr);//这里是做了优化,在递归方法外面创建一个专门用于存放每次递归是存放临时有序子数组的数组
        subSort(arr, 0, int(len-1), temp);
    }
    
    void subSort(vector<int>& arr, int left, int right, vector<int>& temp){
        if (left < right) {
            int mid = (left + right)/2;
            subSort(arr, left, mid, temp);//左序列归并排序,使得左序列有序
            subSort(arr, mid+1, right, temp);//右序列归并排序,使得右序列有序
            merge(arr, left, mid, right, temp);//将两个有序子数组做合并操作
        }
        
    }
    
    /*MergeSort.cpp*/
    void merge(vector<int>& arr, int left, int mid, int right, vector<int>& temp){
        int i = left;//左序列指针
        int j = mid + 1;//有序列指针
        int p = 0;//临时数组指针
        while (i <= mid && j <= right) {
            if (arr[i] <= arr[j]) {
                temp[p++] = arr[i++];
            }else {
                temp[p++] = arr[j++];
            }
        }
        //将左边剩余元素填充到temp中
        while (i <= mid) {
            temp[p++] = arr[i++];
        }
        //将右序列剩余元素填充进temp
        while (j <= right) {
            temp[p++] = arr[j++];
        }
        p = 0;
        //将temp中的元素全部拷贝到原数组中
        while(left <= right) {
            arr[left++] = temp[p++];
        }
    }
    
    
    
    /*main*/
    #include <iostream>
    #include <vector>
    using namespace std;
    int main(int argc, const char * argv[]) {
            vector<int> arr4= {7, 5, 3, 2, 4, 9, 1, 8, 6, 0};
        cout << "arr4: " << endl;
        for (int i = 0; i < 10 ; i++) {
            cout << arr4[i] <<" ";
        }
        cout << endl;
        MergeSort mergeSort = MergeSort();
        mergeSort.sort(arr4, 10);
        cout << "merge sorted arr4: " << endl;
        for (int item : arr4) {
            cout << item <<" ";
        }
        cout << endl;
    
    }
    

    控制台输出结果

    //bash
    arr4: 
    7 5 3 2 4 9 1 8 6 0 
    merge sorted arr4: 
    0 1 2 3 4 5 6 7 8 9 
    Program ended with exit code: 0
    
  • 相关阅读:
    每日一题 为了工作 2020 0412 第四十一题
    每日一题 为了工作 2020 04011 第四十题
    每日一题 为了工作 2020 0410 第三十九题
    每日一题 为了工作 2020 0409 第三十八题
    每日一题 为了工作 2020 0408 第三十七题
    每日一题 为了工作 2020 0407 第三十六题
    每日一题 为了工作 2020 0406 第三十五题
    每日一题 为了工作 2020 0405 第三十四题
    学习总结(二十四)
    学习总结(二十三)
  • 原文地址:https://www.cnblogs.com/wjw-blog/p/13275072.html
Copyright © 2011-2022 走看看