歸併排序 及拓展 逆序對

2022-05-25 03:27:13 字數 1594 閱讀 1846

時間複雜度

歸併排序時間複雜度為o(nlogn)

似乎和快速排序差不多,但在有些特定的場合下,歸併排序卻能起到快速排序達不到的效果(如一年的聯賽題,瑞士輪)

思路及實現

歸併排序分為兩個步驟,分、合;

分 的過程我們用二分的思路實現;

合 的過程時間複雜度可達到o(n);

分:進行分治:

假設當前處理的區間為l~r;

實現:過程定義:void merge_sort(int l,int r)

merge_sort(l,l+r>>1);

merge_sort(l+r>>1+1,r);

合:

過程定義:void merge_group(int l,int r)

void merge_group(int l,int r)

while(isdigit(chr))

return ans*f;

}int a[100],b[100],n;

void merge_group(int l,int r)//手打合併

return;

}int main()

{ n=read();

for(int i=1;i<=n;i++)

cin>>a[i];

merge_sort(1,n);

for(int i=1;i<=n;i++)

cout《什麼是逆序對呢?

給定一組數列若其中存在ia[j],那麼這就是一組逆序對

看下面一組例子

5 4 2 6 3 1

其中逆序對有

5 45 2

5 35 1

4 24 3

4 12 1

6 36 1

3 1共11組

樸素演算法:o(n^2) //顯然資料過大便無法接受

for(int i=1;ia[j]) ans++;

演算法公升級:o(n logn)

思路:歸併排序

在歸併排序的合併步驟中,假設將兩個有序陣列a 和有序陣列b 和並為乙個有序陣列c。計算逆序對問題轉換為計算逆序對(a,b)的問題,其中a來自a, b來自b。當a < b的時候,不計數,當a>b的時候(a,b)就是逆序對,由於a是有序的,那麼a中位於a之後的元素對於b中的元素b也形成了逆序對,於是對於逆序對(a,b),(假設a的起始下標為sa,結束下標為ea,a的下標為pos)實際上合併成c後會會產生ea-pos+1個逆序對。

(我覺得,這一塊我自己可能不能講得很清楚,所以...............以上內容摘自流動的城市的部落格

好了,這時便不得不手打合併過程了

但在合併原程下加一丟丟改變就ok了

修改合併的過程,其他不變

void merge_group(int l,int r)

{ int i=l,mid=l+r>>1,j=mid+1;

for(int k=l;k<=r;k++)

if(j>r||i<=mid&&a[i]附上練習題目cow photographs(usaco2010nov)

歸併排序及逆序對演算法

排序都用qsort了,別的排序演算法不怎麼用,但有些排序的思想很重要。碰到一道求逆序對的題,要用到歸併排序,學習了一下歸併排序。歸併排序是用分治思想,分治模式在每一層遞迴上有三個步驟 分解 將n個元素分成個含n 2個元素的子串行。解決 用合併排序法對兩個子串行遞迴的排序。合併 合併兩個已排序的子串行...

《泛》 歸併排序 及 逆序對

今天寫乙個歸併排序的模板,返回值為該序列的逆序對數 基本思路 歸併排序就是利用二分的思想,將區間無限遞迴二分,直到當前劃分區間只包含乙個元素或沒有元素的時候 我們認為這個序列是自動有序的 我們回溯到上一層,然後將當前層的左右兩個區間合併為乙個有序序列,然後繼續回溯,回溯之後,當前層的左右兩個區間都應...

逆序對 (歸併排序)

逆序對的nlogn方法,改進後的歸併排序 給定排列p,求排列的逆序對數量。p的長度 100000。要求o nlogn 定義歸併排序過程merge l,r merge l,r merge l,mid merge mid 1,r count l,mid,mid 1,r 只需要考慮左右兩段之間造成的逆序對...