5.归并排序

5.归并排序

5.1归并排序的思想和复杂度

归并排序思想

归并排序主要是分治法的思想,有自顶向下和自底向上的归并排序。
归并排序通过递归将一个数组一分为二,然后将两个数组分别进行排序,对两个数组又进行划分,划分成四个数组,依次类推,直到将整个数组分解完毕。每次将数组进行二分后,需要将两个排序完毕的数组进行归并。例如,将8个数组归并成4个数组,4个数组归并成2个数组,2个数组归并成1个数组。最后就完成了整个数组的排序.

时间和空间复杂度

时间复杂度如表所示

算法 平均情况 最好情况 最差情况
冒泡 O(NlogN) O(NlogN) O(NlogN)

空间复杂度:O(N)

5.2归并排序的操作

假设有这样一个数组vec:

下标 0 1 2 3 4 5 6 7 8 9
数组 9 8 7 6 5 4 3 2 1 0

归并方法

先上代码

    void merge(vector &aux,vector &vec,int lo,int mid,int hi)
    {
        int i=lo,j=mid+1;
        for(int k=lo;k<=hi;k++)
        {
            aux[k]=vec[k];
        }
        for(int k=lo;k<=hi;k++)
        {
            if(i>mid)               vec[k]=aux[j++];
            else if(j>hi)           vec[k]=aux[i++];
            else if(aux[i]>aux[j])  vec[k]=aux[j++];
            else                    vec[k]-aux[i++]; //if(aux[i]<=aux[j])
        }
        show(vec);
    }

归并排序中最关键的一步就是将两个子数组进行归并。上面的merge函数中,需要提供一个辅助数组aux,原数组vec,以及需要归并的索引lo,mid,hi。其中,lomid是前半部分子数组,mid+1hi是后半部分子数组。归并完成后就将原数组vec的vec[lo]~vec[hi]完成了排序。

自顶向下的归并排序

    void sort_ub(vector &vec)
    {
        vector aux(vec.size());
        sort_ub(aux,vec,0,vec.size()-1);
    }
    void sort_ub(vector &aux,vector &vec,int lo,int hi)
    {
        if(hi<=lo)return;
        int mid = lo+(hi-lo)/2;
        sort_ub(aux,vec,lo,mid);
        sort_ub(aux,vec,mid+1,hi);
        merge(aux,vec,lo,mid,hi);
    }

递归分治

  1. 每次sort_ub找到lo和hi中间的mid,
  2. 将前半部分vec[lo]~vec[mid]排序
  3. 将后半部分vec[mid]~vec[hi]排序
  4. 将vec[lo]~vec[hi]归并

自底向上的归并排序

    sort_bu(vector &vec)
    {
        vector aux(vec.size());
        sort_bu(aux,vec);

    }
    sort_bu(vector &aux,vector &vec)
    {
        int number=vec.size();
        for(int sz=1;sz

自底向上:

  1. 将整个数组进行两两划分,划分到子数组的长度为sz=1。

  2. 然后长度为sz的数组两两进行归并
    sz=1时,整个数组有N=vec.size()个子数组
    sz=2时,整个数组有N/2个子数组
    sz=4时,整个数组有N/4个子数组
    ..................
    sz=N时,整个数组有N/N=1个数组,这个时候就归并完毕了

  3. 边界条件:如果数组vec的长度不为2的幂,那么最后一次归并可能不是两两对称的,因此需要加一个边界条件lo+(sz-1)+sz

自底向上的归并过程中,前一次操作中已经完成排序,每一次的操作就是将分散的子数组合并成一个个更长的数组,最后完成整个数组的排序
OK, 可以上代码了。

5.3 C++代码

#include 
#include 
using namespace std;

class Sort
{
public:
    void sort_ub(vector &vec)
    {
        vector aux(vec.size());
        sort_ub(aux,vec,0,vec.size()-1);
    }
    void sort_ub(vector &aux,vector &vec,int lo,int hi)
    {
        if(hi<=lo)return;
        int mid = lo+(hi-lo)/2;
        sort_ub(aux,vec,lo,mid);
        sort_ub(aux,vec,mid+1,hi);
        merge(aux,vec,lo,mid,hi);
    }
    sort_bu(vector &vec)
    {
        vector aux(vec.size());
        sort_bu(aux,vec);

    }
    sort_bu(vector &aux,vector &vec)
    {
        int number=vec.size();
        for(int sz=1;sz &aux,vector &vec,int lo,int mid,int hi)
    {
        int i=lo,j=mid+1;
        for(int k=lo;k<=hi;k++)
        {
            aux[k]=vec[k];
        }
        for(int k=lo;k<=hi;k++)
        {
            if(i>mid)               vec[k]=aux[j++];
            else if(j>hi)           vec[k]=aux[i++];
            else if(aux[i]>aux[j])  vec[k]=aux[j++];
            else                    vec[k]-aux[i++]; //if(aux[i]<=aux[j])
        }
        show(vec);
    }
    void show(vector &vec)
    {
        for(int i=0;i init()
    {
        vector vec;
//        int arr[10]={4,3,5,2,1,9,8,6,0,7};
        int arr[10]={9,8,7,6,5,4,3,2,1,0};
        vec.insert(vec.begin(),arr,arr+10);
        cout <<"ori:"< &vec)
    {
        for(int i=0;ivec[i+1])return false;
        }
        return true;
    }
private:
    void exch(vector &vec,int a,int b)
    {
        int tmp;
        tmp=vec[a];
        vec[a]=vec[b];
        vec[b]=tmp;
    }
};

int main()
{
    Sort sortob;
    vector mvec=sortob.init();
//    sortob.sort_ub(mvec);
    sortob.sort_bu(mvec);
    cout <<"------result-------"<

输出结果:

image.png

你可能感兴趣的:(5.归并排序)