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

    归并排序

      归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使  每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

      首先盘点一下C++的各种排序算法:qsort(快速排序), merge_sort(归并排序), heap_sort(堆排序),以及最为强大的sort,这个函数的实现我们并不能够确定他将用什么排序算法。
      排序算法那么多,为什么只有归并排序需要详细学习实现呢?

      首先归并排序是分治思想的重要代表,其实分治的代码大部分都与归并排序非常类似。而且归并排序还可以用来求逆序对。

    核心思想:
      对[l, r]进行排序时,先对[l, m]和[m + 1, r]进行排序,然后对两个有序数列进行合并。

      其中对两个有序数字的合并是用两个指针O(1) 实现的。每次归并时从两个数组中求最小值,而最小值有一定是左边数组的第一个或右边数组的第一个,于是可以用两个指针对两个数组扫描来实现。

    #include <algorithm>
    #include <iostream>
    #include <cstring> 
    
    using namespace std;
    
    const int MAXN = 12000;
    
    int a[MAXN]; //原数组
    int b[MAXN]; //中间数组 
    int ans = 0; //逆序对个数 
    
    void mergesort(int l, int r) //归并排序 
    {
        if (l == r) return;
        int mid = (l + r) >> 1;
        mergesort(l, mid);
        mergesort(mid + 1, r); 
    
        int p1 = l, p2 = mid + 1;
        for (int i = l; i <= r; ++i)
            if (p1 <= mid)
                if (p2 <= r)
                    if (a[p1] < a[p2]) b[i] = a[p1++];
                    else b[i] = a[p2++];
                else b[i] = a[p1++];
            else b[i] = a[p2++];
        for (int i = l; i <= r; ++i) a[i] = b[i];
    }
    
    void mergesort(int l, int r) //求逆序对个数 
    {
        if (l == r) return;
        int mid = (l + r) >> 1;
        mergesort(l, mid);
        mergesort(mid + 1, r);
        
        int p1 = l, p2 = mid + 1;
        for (int i = l; i <= r; ++i)
            if (p1 <= mid)
                if (p2 <= r)
                    if (a[p1] < a[p2]) b[i] = a[p1++];
                    else b[i] = a[p2++], ans += mid - p1 + 1;
                else b[i] = a[p1++];
            else b[i] = a[p2++];
        for (int i = l; i <= r; ++i) a[i] = b[i];
    }
  • 相关阅读:
    Bootstrap留言板界面练习
    Bootstrap 学习
    web | [GXYCTF2019]禁止套娃
    re | [GKCTF2020]WannaReverse
    PE文件结构 | 在PE文件的空白区添加代码
    PE文件结构 | RVA与FOA的转换
    re | [NPUCTF2020]BasicASM
    win32 | WinSock2网络编程 | socket-tcp通信
    web | flask 修饰器实现原理
    运维 | 配置LNMP | 基于docker.ubuntu:16.04
  • 原文地址:https://www.cnblogs.com/yanyiming10243247/p/9483679.html
Copyright © 2011-2022 走看看