分治演算法(一)--歸併排序
阿新 • • 發佈:2019-01-31
歸併排序
最近上演算法課,老師講到分治演算法那塊了,感覺上課是認真聽了的,可是那個段子手老師講幾個笑話我就忘完了,很尷尬,所以以後她每講一章,自己還是總結下哈
分治演算法的理解
就我個人來說,對分治演算法理解很簡單,就三個字 分 解 合
分:就是把大問題轉換成一個一個的小問題
解:將小問題一個一個按照某種方式解決
合:利用小問題的結果去得出最終大問題的答案
就如同古時候打仗想佔領一個王國,我可以把那個王國領地分成很多份,然後然後一塊塊地佔領征服,最後把那一塊塊佔領之後,就可以把那個王國佔領了
但是說起來簡單,也有很多難點
1.不知道如何將問題化成小問題
2.不知道將小問題聯絡起來
3.大問題和小問題之間結果的關係
歸併排序
歸併排序歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治的一個非常典型的應用。
簡單的來說就是就是分而治之的思路
先把陣列元素一個一個分開
然後兩個兩個合在一起排好序
然後四個四個合在一起排好序
依此類推
直到陣列的一半和另一半排好序,這個問題就解決了
其實這個思路很簡單,唯一要解決的就是然後將兩個數組合並排好序
我們需要將兩個已經有序的子序列合併成一個有序序列,比如上圖中的最後一次合併,要將[4,5,7,8]和[1,2,3,6]兩個已經有序的子序列,合併為最終序列[1,2,3,4,5,6,7,8],來看下實現步驟。
合併排序程式碼實現//java版的
import java.util.Arrays;
public class MergerSort {
public static void merge(int[]a,int low,int mid,int high){
int []temp = new int[high-low+1];
int i = low;
int j = mid+1;
int k = 0;
while(i<=mid&&j<=high){
if(a[i]<a[j]){
temp[k++] = a[i++];
}else {
temp[k++] = a[j++];
}
}
while(i <= mid){
temp[k++] = a[i++];
}
while(j <= high){
temp[k++] = a[j++];
}
for(int k2 = 0;k2<temp.length;k2++){
a[k2+low] = temp[k2];
}
}
public static void mergeSort(int[]a,int low,int high){
int mid = (low + high)/2;
if(low < high){
mergeSort(a, low, mid);
mergeSort(a, mid+1, high);
merge(a, low, mid, high);
System.out.println(Arrays.toString(a));
}
}
public static void main(String[] args) {
// TODO 自動生成的方法存根
int a[] = {52,45,77,33,4,5,22,77,43};
mergeSort(a, 0, a.length-1);
System.out.println("排序的結果"+Arrays.toString(a));
}
}
輸出結果如下:
總結
對於演算法來說,懂個思路只是最簡單的那塊,實現程式碼才是關鍵,因為思路只是一個引導作用,具體實現,每個人的方法可能不一樣。
以後自己還是勤快點,每天學的東西不能拖了