歸并排序介紹
歸并排序(MERGE-SORT)是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法(Divide and Conquer)的一個非常典型的應用咸产。將已有序的子序列合并惠啄,得到完全有序的序列;即先使每個子序列有序维费,再使子序列段間有序。若將兩個有序表合并成一個有序表丹喻,稱為二路歸并襟铭。
排序過程
將一個數(shù)組分解成兩個子序列碌奉,這兩子序列繼續(xù)分解,直到不能在分解為止寒砖;從最小的子序列開始進行歸并赐劣,形成一個較大的有序子序列,再繼續(xù)歸并直到整個數(shù)組有序哩都。該過程我們可以用遞歸來實現(xiàn)魁兼。排序過程如下圖所示:
歸并排序.png
歸并操作的工作原理
將兩個分別有序的子序列歸并成一個新的較大有序序列,其過程如下:
1.準備一個輔助數(shù)組漠嵌,使其大小為兩個已經(jīng)排序序列之和咐汞,該空間用來存放合并后的序列
2.設定兩個指針p1和p2,最初位置分別為兩個已經(jīng)排序序列的起始位置
3.比較指針p1和p2所指向的元素献雅,選擇相對小的元素放入到合并空間碉考,并移動指針到下一位置
4.重復步驟3直到某一指針超出序列尾
5.將另一序列剩下的所有元素直接復制到合并序列尾
算法實現(xiàn)
public class MergeSort {
private static void mergeSort(int[] arr,int left, int right) {
if(left == right) return;
int mid = left + ((right - left) >> 1); //int mid = (left + right)/2;
mergeSort(arr,left,mid); //左側序列分解
mergeSort(arr,mid+1,right); //右側序列分解
merge(arr,left,mid,right); //歸并
}
private static void merge(int[] arr,int left,int mid,int right) {
int[] help = new int[right - left + 1]; //準備輔助數(shù)組
//準備兩個指針分別指向兩個序列的開始
int p1 = left;
int p2 = mid + 1;
int i = 0;
/*
* 比較指針p1和p2所指向的元素,選擇相對小的元素放入到合并空間挺身,并移動指針到下一位置,
* 直到某一指針超出序列尾
* */
while(p1 <= mid && p2 <= right) {
help[i++] = (arr[p1] < arr[p2])?arr[p1++]:arr[p2++];
}
//p2指針超出序列尾,將左側序列繼續(xù)添加進輔助數(shù)組
while(p1 <= mid) {
help[i++] = arr[p1++];
}
//p1指針超出序列尾锌仅,將右側序列繼續(xù)添加進輔助數(shù)組
while(p2 <= right) {
help[i++] = arr[p2++];
}
//拷貝會原數(shù)組
for(int j = 0; j < help.length; j++) {
arr[left + j] = help[j];
}
}
public static void mergeSort(int[] arr) {
if(arr == null || arr.length < 2) return;
mergeSort(arr,0,arr.length-1);
}
//測試
public static void main(String[] args) {
int[] arr0= {10,4,6,3,8,2,5,7};
mergeSort(arr0);
for(int i=0; i<arr0.length; i++) {
System.out.print(arr0[i] + " ");
}
//2 3 4 5 6 7 8 10
System.out.println();
int[] arr1 = {10,9,8,7,6,5,4,3,2,1};
mergeSort(arr1);
for(int i=0; i<arr1.length; i++) {
System.out.print(arr1[i] + " ");
}
//1 2 3 4 5 6 7 8 9 10
}
}
復雜度
在排序中由于我們使用了輔助數(shù)組章钾,所以額外空間復雜度為O(n);
由歸并排序的遞歸公式:T(N) = 2T(N/2) + O(N) 可知時間復雜度為O(NlogN)
算法的復雜度與master定理:http://www.gocalf.com/blog/algorithm-complexity-and-master-theorem.html