時間複雜度
歸併排序時間複雜度為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)
演算法公升級:o(n logn)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樸素演算法:o(n^2) //顯然資料過大便無法接受其中逆序對有
5 45 2
5 35 1
4 24 3
4 12 1
6 36 1
3 1共11組
for(int i=1;ia[j]) ans++;
思路:歸併排序
在歸併排序的合併步驟中,假設將兩個有序陣列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 只需要考慮左右兩段之間造成的逆序對...