歸併排序

沒有幾個寫歸併排序的dalao?c++

我翻了好幾頁,就看到一位dalao寫了歸併排序,並且沒有任何說明和註釋
,也有多是我眼睛很差使,望各位dalao和管理見諒數組

原本要寫逆序對這個題,而後來這裏先聯繫一下歸spa

歸併排序利用的是分治思想

假若有兩個已經排好序的序列,你怎麼合併他們?

舉個例子吧,咱們搞兩個指針l和r,初始時令他們=各自序列第一個數的位置指針

1 4 10code

2 11 15排序

那麼a[l] 就等於1,a[r]就等於2遞歸

(1)首先a[l] < a[r]ci

咱們將a[l]加入另外一個待選數列t[] = {1};
而後l++get

(2)如今a[l] > a[r]it

把a[r]加入t[] = {1,2}
而後r++

(3)而後a[l] < a[r]

a[l] 加入t[] = {1,2,4}
l++

(4)a[l] < a[r]

a[l] 加入t[] = {1,2,4,10}
,而後l++

咱們如今發現l > 第一個數組的長度,表明第一個數組的最大值也不如a[r] 及a[r]以後的數大,因此把剩下數全加進去

最終t[] = {1,2,4,10,11,15}

那麼咱們怎麼獲得兩個有序的數列呢?

咱們發現,若是一個數列只有一個數,那麼它是有序的,這樣咱們就能夠遞歸解決問題,遞歸到1就返回,由於已經排好了

以上就是龜排的過程

#include<bits/stdc++.h>
//萬能頭
using namespace std;

inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;}
//快讀
int p[400001],t[400001];//p是須要排序的數列
//t的做用在上面已經說了,至關於一個臨時數組

int k;

void gb(int x,int y){
    if(x == y) return;//若是隻有一個數,那麼它是有序的
    int mid = (x + y) >> 1; //從中間分開
    gb(x,mid);//遞歸左半邊
    gb(mid + 1,y);//右半邊
    int l = x,r = mid + 1,tot = 0;//第一個區間的指針是l,第二個是r,tot是計算t[]中有多少數
    for(int i = x;i <= y;++i){
        if(p[l] > p[r]){//這就是上述排序過程
            t[++tot] = p[l++];
            if(l > mid) break;//指針超過範圍退出
        }
        else{
            t[++tot]  = p[r++];
            if(r > y) break;
        }
    }
    if(l > mid){//左邊超範圍把右邊加上
        for(int i = r;i <= y;++i) t[++tot] = p[i];
    }
    if(r > y){//同理
        for(int i = l;i <= y;++i) t[++tot] = p[i];
    }
    for(int i = x;i <= y;++i){//把臨時數組的值賦給真實的數組
        p[i] = t[i - x + 1];
    }
}

int main(int argc, char const *argv[])
{
    int n;
    cin>>n;
    for(int i = 1;i <= n;++i){
        p[i] = read();
    }
    gb(1,n);
    for(int i = n;i >= 1;--i){
        cout<<p[i]<<" ";
    }
    cout<<endl;
    int AC = 0;
    return AC;//返回AC
}
相關文章
相關標籤/搜索