歸併排序與逆序數

2021-10-02 08:49:38 字數 2573 閱讀 9470

家好呀,這裡是菜鳥小初,今天我們一起來學習一下所謂的歸併排序,首先歸併排序是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法的乙個非常典型的應用。將已有序的子串行合併,得到完全有序的序列;即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為二路歸併。歸併排序是一種穩定的排序方法。然而,歸併排序在應用方面還是大大不如快速排序的,只有針對一些特殊問題應用歸併才最方便,比如說我們今天要著重討論的逆序數。

當然我們要先來看看歸併的原理,這裡的歸併操作採用了遞迴的思想,指的是將兩個順序序列合併成乙個順序序列的方法。

如 設有數列初始狀態:6,202,100,301,38,8,1

第一次歸併後:,,,,比較次數:3;

第二次歸併後:,,比較次數:4;

第三次歸併後:,比較次數:4;

總的比較次數為:3+4+4=11;

逆序數為14;

歸併操作的工作原理如下:

第一步:申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列;第二步:設定兩個指標,最初位置分別為兩個已經排序序列的起始位置;第三步:比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置重複步驟3直到某一指標超出序列尾。將另一串行剩下的所有元素直接複製到合併序列尾

好了,將原理複述完以後我們來康康**

void

mergesort

(long

long

int a,

long

long

int first,

long

long

int last,

long

long

int temp)

}

這個函式利用了遞迴的思想,每次先把自己分成倆部分,這裡又用到了二分,因為時間的緣故,我們就不細說這倆中演算法了,最後merge這個函式的作用是為了使基本有序的兩個陣列合併的操作,接下來我們來康康這個函式

void

merge

(long

long

int a,

long

long

int first,

long

long

int middle,

long

long

int last,

long

long

int temp)

if(i==middle+1)

if(j==last+1)

for(l=

0; l1; l++

) a[first+l]

=temp[l]

;

通過將乙個陣列分成前後兩個部分,相互進行比較後插入,這樣闊以大大減小時間複雜度

我們要求逆序數的話,只需要在歸併的基礎上加一段話

void

merge

(long

long

int a,

long

long

int first,

long

long

int middle,

long

long

int last,

long

long

int temp)

}if(i==middle+1)

if(j==last+1)

for(l=

0; l1; l++

) a[first+l]

=temp[l]

;

這段話的意思是當檢測到前面的數比後面的數大的時候那麼從那個數開始後面 的所有數都大於那個數,加上它本身也大於那個數,所有需要加上1再由mid減去那個數的位置i

在最後,當然也要給大家康康完整的**

#include

long

long

int nxs;

void

merge

(long

long

int a,

long

long

int first,

long

long

int middle,

long

long

int last,

long

long

int temp)

}if(i==middle+1)

if(j==last+1)

for(l=

0; l1; l++

) a[first+l]

=temp[l];}

void

mergesort

(long

long

int a,

long

long

int first,

long

long

int last,

long

long

int temp)

}int

main()

}

逆序數與歸併排序

逆序數指數組中前面的數大於後面的數的對數 a i a j 並且i將陣列分為兩組l 左 陣列和 右 r陣列 將l陣列與r陣列分別從小到大排序 在用r陣列與左陣列逐個比較,假如右陣列的數比左陣列的第乙個數小,則cnt加上左陣列的大小,右陣列的數比左陣列的第乙個數大,比左陣列的第二個數小則cnt加上左陣列...

逆序數與歸併排序

終於找到一篇能get到的文章 tips 3,5,7,8和2,6,9,10歸併的例子,所有部落格插圖位置都不對,都插在了2,3,6,8,9和1,4,7,10,50的例子的後面,需要理解的是 每次歸併過程中,當且僅當右側的數提前放到左側,而左側還未放置的個數就是該元素減少的逆序個數 舉例 2要往第乙個位...

歸併排序 逆序數

對於數列a,將其二分地拆分為b,c 先將b,c分別排序好,再合併b,c即為總的排序,不過在合併的過程中我們可以算出逆序數哦。其原理網上很多,我這裡不再贅述,只給出實現 include include define ll long long using namespace std ll mergeso...