zoukankan      html  css  js  c++  java
  • 【C++】归并排序

    性能分析:

      时间复杂度:O(n*log(n))

      空间复杂度:O(n)

    归并排序算法来自于分而治之思想,“归”是“递归”的意思,“并”是"合并“的意思,就是说将复杂的数组排序问题先进性分解,然后递归的解决小问题,最后合并问题的解。

    #include<iostream>
    #include<vector>
    using namespace std;
    void sort_merge_recursive(vector<int>& data, int left, int right);
    void merge(vector<int>& data, int left, int mid, int right);
    
    int main()
    {
        // 首先找出待排序列中最小的数,然后用这个数和原序列中的第一个数交换位置;
        // 其次,找出第二小的和原第二个数交换位置;
        // 依次顺序直到找到第二大的数,之后原数列完全变成有序数列.
        vector<int> data = { 3,0,5,2,7,8,9,6,1 };
        //获取序列元素个数
        int length = 9;
        int left = 0;
        int right = 8;
        sort_merge_recursive(data, left, right);
    
        for (int i = 0; i < length; i++)
        {
            cout << data[i] << "   ";
        }
    }
    
    void sort_merge_recursive(vector<int> &data, int left, int right)
    {
        if (left < right)//暗含如果left>=right就不做任何操作,因为这个时候表示已经分解到只剩一个元素了,天然有序
        {
            //将序列一分为二获取中间位置
            int mid = (left + right) / 2;
            //递归处理两个子序列使之有序
            sort_merge_recursive(data, left, mid);
            sort_merge_recursive(data, mid + 1, right);
            //合并两个有序子序列
            merge(data, left, mid, right);
        }
    }
    
    void merge(vector<int> &data, int left, int mid, int right)
    {
        //将有序的两个子序列合并起来
        //获取两个子序列的第一个元素
        int i = left;
        int j = mid + 1;
        //创建临时容器来保存合并结果,同时指定容器大小
        vector<int> temp;
        temp.resize(right - left + 1);//从图中最底下开始往上合并,每一次因为要合并两个子序列,所以容器大小要从新设置
        //开始合并
        int k = 0;//临时容器的索引
        while (i <= mid && j <= right)
        {
            if (data.at(i) <= data.at(j))//如果左边的值元素值小于右边的
            {
                temp.at(k++) = data.at(i++);//先把小的放到数组前面
            }
            else
            {
                temp.at(k++) = data.at(j++);
            }
        }
        //到这里肯定已经有一个子序列的所有元素已经完全放到了容器里,接着放另一个剩下的元素
        while (i <= mid)//因为不知道是哪个完全放进去了,用这种方式来判断
        {
            temp.at(k++) = data.at(i++);
        }
        while (j <= right)
        {
            temp.at(k++) = data.at(j++);
        }
    
        //只能通过这样的方式将临时容器元素复制给原始容器得到结果
        for (int n = 0; n < k; n++)
        {
            data.at(left++) = temp.at(n);
        }
    }
  • 相关阅读:
    写一点gil锁吧,其实真的我感觉没啥关系。
    《Effective Python》59个有效方法(今日到25)
    《Python学习笔记本》第五章 迭代器 笔记以及摘要(完结)
    《Python学习笔记本》第四章 函数 笔记以及摘要(完结)
    《Python学习笔记本》第三章 表达式 笔记以及摘要(完结)
    java 之冒泡排序
    Apache Tomcat 之路(三 部署多个应用)
    Apache Tomcat 之路(二 部署web 应用程序)
    Apache Tomcat 之路(一 基本概念)
    移动端 H5 拍照 从手机选择图片,移动端预览,图片压缩,图片预览,再上传服务器
  • 原文地址:https://www.cnblogs.com/masbay/p/14032226.html
Copyright © 2011-2022 走看看