《泛》 歸併排序 及 逆序對

2022-05-23 01:24:09 字數 2407 閱讀 3238

今天寫乙個歸併排序的模板,返回值為該序列的逆序對數

基本思路

歸併排序就是利用二分的思想,將區間無限遞迴二分,直到當前劃分區間只包含乙個元素或沒有元素的時候(我們認為這個序列是自動有序的),我們回溯到上一層,然後將當前層的左右兩個區間合併為乙個有序序列,然後繼續回溯,回溯之後,當前層的左右兩個區間都應該分別是已經經過合併的有序子區間,我們將這兩個有序子區間再進行有序合併,再返回上一層,直到返回最大區間,則合併最大區間的左右有序子區間,得到有序序列。

流程演示

比如:22  3  1  5  4

7  9  1  8  0

紅色區間劃分:22  3

1  5  4

左邊:22

3       右邊

15   4

左邊:合併有序:3   22

右邊:5  4區間遞迴返回時候變為:4 5

右邊合併:1  4  5

左右區間合併為乙個區間:1  3  4  5  22

至此左側區間處理完畢

右側區間同理,得到有序序列:0  1  7  8  9

最後合併整個區間

0  1  1  3  4  5  7  8  9  22

逆序對數

我們利用歸併的思想,它會將每個區間細分到最小,返回整合的時候,會進行左右區間合併,合併的時候就要比較左右區間當前值那個大,然後取小的那個,我們可以在比較的時候做記錄,如果左側的值小於右側,我們就做記錄,這樣一路回溯,就會找到所有的逆序對數。

我們利用歸併排序的返回值來將此記錄值輸出到外部

泛型**:

templateint merge_sort(const value_ptr& begin, const value_ptr&end)

; //

記錄逆序對數

if (end - begin <= 1)return0;

value_ptr mid = begin + (end - begin) / 2

; merge_sort

(begin, mid);

merge_sort

(mid, end);

//將上述兩段區間順序排列

value_ptr l = begin, r =mid;

int k, index;

while (l < mid && r

if (*l < *r)to[k++] = *l++;

else

//如果左側值小於右側

while (l < mid)to[k++] = *l++;

while (r < end)to[k++] = *r++;

for (index = 0; begin + index < end; ++index)*(begin + index) =to[index];

return

cnt;

}

測試與使用

#include #include 

using

namespace

std;

intmain()

; vector

v;int cnt = merge_sort(list + 0, list + 10

); merge_sort

(v.begin(), v.end());

for (auto it : v)cout << it << "";

cout

<

for (auto it : list)cout << it << "";

cout

<

cout

<< "

逆序對數:

"<< cnt << endl <

char list_[10];

vector

v_;cnt = merge_sort(list_ + 0, list_ + 10

); merge_sort

(v_.begin(), v_.end());

for (auto it : v_)cout << it << "";

cout

<

for (auto it : list_)cout << it << "";

cout

<

cout

<< "

逆序對數:

時間複雜度為:o(n * log n)

歸併排序及逆序對演算法

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

歸併排序 及拓展 逆序對

時間複雜度 歸併排序時間複雜度為o nlogn 似乎和快速排序差不多,但在有些特定的場合下,歸併排序卻能起到快速排序達不到的效果 如一年的聯賽題,瑞士輪 思路及實現 歸併排序分為兩個步驟,分 合 分 的過程我們用二分的思路實現 合 的過程時間複雜度可達到o n 分 進行分治 假設當前處理的區間為l ...

逆序對 (歸併排序)

逆序對的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 只需要考慮左右兩段之間造成的逆序對...