void merge(int (&a)[8], int left, int mid, int right)
la[nla] = max_num; //哨兵
for (int i = 0; i < nra; ++i)
ra[nra] = max_num; //哨兵
int i = 0;
int j = 0;
for (int k = left; k <= right; ++k)
else
}}void merge_sort(int (&a)[8], int start_pos, int len)
int half = len / 2;
merge_sort(a, start_pos, half);
merge_sort(a, start_pos + half, len - half);
int mid_pos = 0;
if (len % 2 == 0) //若長度為偶數,中位數取左邊的乙個, 以方便merge函式處理
else
merge(a, start_pos, mid_pos, start_pos + len - 1); }
void display(int (&a)[8], int len)
cout << endl;
}int main(int argc, char* argv)
; display(a, 8);
merge_sort(a, 0, 8);
display(a, 8);
getchar();
return 0;
}
逆序對問題定義:假設a[1..n]是乙個有n個不同數的陣列。若ia[ j ],則對偶(i, j)稱為a的乙個逆序對。
用歸併排序很好解決這個問題,在merge函式裡面,有兩個有序陣列,左邊的有序陣列la,右邊的有序陣列ra。在歸併la和ra時判斷兩陣列中元素大小,如果存在la[ i ] > ra[ j ] (i < j),那麼逆序對數量就+1。
由於la和ra存在哨兵max_num,由於哨兵的存在而使得la[ i ] > ra[ j ] (i < j),這種情況不能算作是逆序對。比如:
逆序對 (歸併排序)
逆序對的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,...