重拾個人算法思惟之--歸併排序

歸併排序算法

算法平均時間複雜度:O(nlog2n)數組

算法空間複雜度:O(n)  (用於存儲有序子序列合併後有序序列)spa

原理:所謂歸併排序是指將兩個或兩個以上有序的數列(或有序表),合併成一個仍然有序的數列(或有序表)。這句話講的很是明白,有序,前提就是有序code

步驟分析:blog

一、劃分子集排序

二、合併子集遞歸

先說一下歸併算法合併的思路,也是核心:(升序)假設有一數組,分紅兩個子數組,子數組每次分別各取出一個數字進行比較(子數組取的元素索引都從小到大),將小的放入準備好的臨時數組,當兩個字數組中有一個數組的全部元素都比較過了,那就將另外一數組剩餘的元素依次放入臨時數組中。那麼這一趟結果就是有序排列好了。前提是兩個子數組都是有序的。舉個栗子:索引

1)假設有數組 [12,5,8,14,7,6](子數組無序class

先劃分爲兩個子數組[12,5,8],[14,7,6],並有一個臨時數組temp[]原理

12 與 14 比較, 12放入temp[]中          temp[12]

5 與 14 比較, 5  放入temp[]中          temp[12,5]

8 與 14 比較, 8  放入temp[]中          temp[12,5,8]

子數組中[12,5,8]全部元素都比較完,剩餘的另外子數組元素依次放入temp[]          temp[12,5,8,14,7,6]

可見子數組無序獲得的結果並非排好序的。

2)假設有數組 [5,8,12,6,7,14](子數組有序

先劃分爲兩個子數組[5,8,12],[6,7,14],並有一個臨時數組temp[]

5   與 6   比較, 5  放入temp[]中          temp[5]

8 與 6   比較, 6  放入temp[]中          temp[5,6]

8 與 7   比較, 7  放入temp[]中          temp[5,6,7]

8 與 14 比較, 8  放入temp[]中          temp[5,6,7,8]

12 與 14 比較, 12放入temp[]中          temp[5,6,7,8,12]

子數組中[5,8,12]全部元素都比較完,剩餘的另外子數組元素依次放入temp[]          temp[5,6,7,8,12,14]

可見子數組有序獲得的結果是排序好的。

怎樣才能保證兩邊子數組是有序?當一個數組只有一個元素的時候,即算爲有序的,而後用上面的第二個例子的思路歸併,即爲排序好的。

也就是說咱們要先將要比較的數組arr[],拆分爲和數組arr.length一樣多的子數組,而後兩兩歸併,如圖1所示:

                            圖1 歸併排序

 

代碼:附註釋

 1 public static void Merge(int[] arr,int low,int mid,int high){  2         int[] temp = new int[high - low + 1];//  3         int i = low;//左邊部分起始索引
 4         int j = mid + 1;//右邊部分起始索引
 5         int index = 0;  6         //比較將較小的放入temp中
 7         while(i <= mid && j <= high){  8             if(arr[i]<arr[j]){  9                 temp[index++] = arr[i++]; 10             }else if(arr[i]>arr[j]){ 11                 temp[index++] = arr[j++]; 12  } 13  } 14         //把左邊剩餘的全放入臨時數組中
15         while(i <= mid){ 16             temp[index++] = arr[i++]; 17  } 18         //把右邊剩餘的全放入臨時數組中
19         while(j <= high){ 20             temp[index++] = arr[j++]; 21  } 22         //最後將臨時數組覆蓋原數組
23         for (int x = 0; x < temp.length; x++) { 24             arr[x+low] = temp[x]; 25  } 26  } 27     public static void MergeSort(int[] arr,int low,int high){ 28         if(low < high){ 29             int mid = (low+high)/2; 30             //將其分爲兩部分
31             MergeSort(arr,low,mid);//左邊遞歸(再分兩部分)
32             MergeSort(arr,mid+1,high);//右邊遞歸(再分兩部分) 33             //歸併
34  Merge(arr,low,mid,high); 35  } 36     }
相關文章
相關標籤/搜索