1. 程式人生 > >分治演算法(一)--歸併排序

分治演算法(一)--歸併排序

歸併排序

最近上演算法課,老師講到分治演算法那塊了,感覺上課是認真聽了的,可是那個段子手老師講幾個笑話我就忘完了,很尷尬,所以以後她每講一章,自己還是總結下哈

分治演算法的理解

就我個人來說,對分治演算法理解很簡單,就三個字 分 解 合
分:就是把大問題轉換成一個一個的小問題
解:將小問題一個一個按照某種方式解決
合:利用小問題的結果去得出最終大問題的答案
就如同古時候打仗想佔領一個王國,我可以把那個王國領地分成很多份,然後然後一塊塊地佔領征服,最後把那一塊塊佔領之後,就可以把那個王國佔領了
但是說起來簡單,也有很多難點
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)); } }

輸出結果如下:
這裡寫圖片描述

總結

對於演算法來說,懂個思路只是最簡單的那塊,實現程式碼才是關鍵,因為思路只是一個引導作用,具體實現,每個人的方法可能不一樣。
以後自己還是勤快點,每天學的東西不能拖了