十大排序 帶你深入了解歸併排序

2021-10-07 23:54:36 字數 3813 閱讀 6884

【2020秋招-面試題目彙總(隨時更新)】

歸併排序,是建立在歸併操作上的一種有效的排序演算法。演算法是採用分治法(divide and conquer)的乙個非常典型的應用,且各層分治遞迴可以同時進行。歸併排序思路簡單,速度僅次於快速排序,為穩定排序演算法,一般用於對總體無序,但是各子項相對有序的數列。

一般求逆序對時,使用!!!

歸併的精髓在於:分而治之

通過上面的**,我們可以看到,歸併排序是將乙個陣列拆分至乙個,在利用merge(歸併)的思想,變成2個、4個、8個等

我們來想想,具體的**應該怎麼實現?

考慮當陣列為0或1時的操作

public

intreversepairs

(int

nums)

int[

] temp =

newint

[len]

;// 利用這個輔助陣列來進行交換

int[

] copy =

newint

[len]

;// 我們儲存乙個原來的陣列,這樣容易看出比較性

for(

int i =

0; i < len; i++

)// 這裡我們的邊界是[0,len-1],輔助陣列為temp

return

reversepairs

(copy,

0, len -

1, temp)

;}

我們怎麼才能把乙個陣列分成一塊一塊,然後再合併呢?

用到了遞迴的思想,我們想一想,終止條件是什麼:當只剩下乙個時,終止,也就是left == right,

我們對左邊進行reversepairs、對右邊進行reversepairs,得到兩個有序的陣列

對他們進行mergeandcount,計算逆序對的值

public

intreversepairs

(int

nums,

int left,

int right,

int[

] temp)

int mid = left +

(right - left)/2

;int leftpairs =

reversepairs

(nums, left, mid, temp)

;int rightpairs =

reversepairs

(nums, mid +

1, right, temp)

;int crosspairs =

mergeandcount

(nums, left, mid, right, temp)

;return leftpairs + rightpairs + crosspairs;

}

再進行mergeandcount,我們就要實現,兩個有序的陣列,怎麼變成乙個陣列:雙指標、依次比較即可

這裡注意兩個地方:

第乙個是邊界的處理,當i == mid + 1 或者 j == right + 1

第二個是count(逆序對的處理)

我們可以看到,5的值是大於4的,也就是5和7都是符合逆序對的,我們觀察可以看出,逆序對的數量也就是左邊陣列剩餘的個數:mid - i + 1

public

intmergeandcount

(int

nums,

int left,

int mid,

int right,

int[

] temp)

int i = left;

int j = mid +1;

int count =0;

for(

int k = left; k <= right; k++

)else

if(j == right +1)

else

if(temp[i]

<= temp[j]

)else

if(temp[i]

> temp[j])}

return count;

}

最後,我們得到這個逆序對的數值,我們來提交一下,看看可不可以通過~

成功通過~~~

// 手撕歸併 -- 逆序對

public

class

demo01

int[

] temp =

newint

[len]

;// 利用這個輔助陣列來進行交換

int[

] copy =

newint

[len]

;// 我們儲存乙個原來的陣列,這樣容易看出比較性

for(

int i =

0; i < len; i++

)// 這裡我們的邊界是[0,len-1],輔助陣列為temp

return

reversepairs

(nums,

0, len -

1, temp);}

public

intreversepairs

(int

nums,

int left,

int right,

int[

] temp)

int mid = left +

(right - left)/2

;int leftpairs =

reversepairs

(nums, left, mid, temp)

;int rightpairs =

reversepairs

(nums, mid +

1, right, temp)

;int crosspairs =

mergeandcount

(nums, left, mid, right, temp)

;return leftpairs + rightpairs + crosspairs;

}public

intmergeandcount

(int

nums,

int left,

int mid,

int right,

int[

] temp)

int i = left;

int j = mid +1;

int count =0;

for(

int k = left; k <= right; k++

)else

if(j == right +1)

else

if(temp[i]

<= temp[j]

)else

if(temp[i]

> temp[j])}

return count;

}}

十大排序演算法 歸併排序

歸併排序是一種概念上最簡單的排序演算法,歸併排序是基於分治法的。歸併排序將待排序的元素序列分成兩個長度相等的子串行,為每乙個子串行排序,然後再將他們合併成乙個子串行。合併兩個子串行的過程也就是兩路歸併。1,申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列 2,設定兩個指標,最初位...

十大排序演算法之歸併排序5

歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。將已有序的子串行合併,得到完全有序的序列 即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為2 路歸併。5.1 演算法描述 5.2 圖例演示...

十大排序演算法之歸併排序(MergeSort)

一 前言 資料結構與演算法,順便刷leetcode,無意間發現了乙個 我覺得講解的比較好的網頁,並且會拿leetcode裡面的題目當做例題,如有需要,奉上 五分鐘學演算法 二 演算法的介紹 分組,將序列的中的元素進行逐層折半分組,直到每組只有乙個元素。歸併,逐層向上排列每一層的元素的順序,然後合併成...