歸併排序是一種利用了分治思想的一種演算法,是我在白書上看到的一種高效的排序演算法,因此學習一下,並在此做下總結,加深理解。(畢竟也不能老是用sort不是?)
首先由此演算法我了解到了一種分治三步法的一種概念(一直對於這些東西雲裡霧裡啊t t)。劃分問題,遞迴求解,合併問題。而歸併排序則非常清晰地完成了這三步。劃分問題便是想要盡可能的把陣列分為兩半,使之變為兩個較小的問題。遞迴便是不斷地將問題劃分地更小。而合併便是問題的關鍵所在了。假設現在最初的兩部分已經排序成功,那麼a,b兩集合必然是有序的。因此我們便可以貪婪地取兩個陣列中最小的數來構成乙個新的集合,而這個集合便是排序好了的。如{1,5,7,8}與{2,9,10,11},先取1,2與5比較取2,5與9比較取5,7與9比較取7……直到兩個集合都為空為止。ok,那麼合併的問題就大功告成了。
#include
#include
const int size=1000;
int a[size],t[size];
int cnt=0;
void merge_sort(int x,int y)
if(y-x>1)//遞迴邊界,當元素個數為2的時候即不再遞迴y-x+1>2
int m=(x+y)/2;
int p=x,q=m,i=x;
merge_sort(x,m);
merge_sort(m,y);
while(p
if(q>=y||(p
else //cnt求的是逆序對數
for(i=x;i
int main()
int n;
while(scanf("%d",&n)!=eof)
for(int i=0;i
cnt=0;
merge_sort(0,n); //為什麼是0~n呢?因為最後一位數是會不參與排序的(q
for(int i=0;i
printf("%d ",a[i]);
printf("%d\n",cnt);
return 0;
逆序對 (歸併排序)
逆序對的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 只需要考慮左右兩段之間造成的逆序對...
歸併排序 逆序對
按照劉汝佳說的,歸併排序分三步 1.劃分問題,即把序列分成元素盡量相等的兩半 2.遞迴求解 3.合併子問題 其實就是把乙個序列不斷的二分,直到只有兩個元素的時候,然後排序,然後返回,再排序。先上 include using namespace std long long a 100005 t 100...
歸併排序(逆序對)
現在我們在競賽中最常用的排序是快速排序,c 只要乙個sort就搞定,但非常明顯,歸併排序的時間複雜度是最優的而且非常穩定,但是人們經常把它用在求逆序對個數上面。那麼下面我用乙個這樣的題來講一下歸併排序。點這裡看題目和樹狀陣列解法。歸併排序是將數列a l,h 分成兩半a l,mid 和a mid 1,...