【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裡面的題目當做例題,如有需要,奉上 五分鐘學演算法 二 演算法的介紹 分組,將序列的中的元素進行逐層折半分組,直到每組只有乙個元素。歸併,逐層向上排列每一層的元素的順序,然後合併成...