轉載請註明出處:http://blog.csdn.net/ljmingcom304/article/details/50378781
本文出自:【梁敬明的博客】
1.歸併排序
歸併排序就是將一個序列拆分成單個元素,兩兩歸併爲新的有序序列,直到將子序列歸併爲一個完整的有序序列爲止。
存在一個序列【4】【7】【8】【6】【5】【9】【3】【0】【2】【1】,從小到大進行排序。
第一次歸併,將兩個元素歸併爲一個子序列,並將子序列按大小順序排列。
第二次歸併,依次取出兩個子序列中較小的值進行排列,將兩個子序列歸併爲一個新的子序列,剩餘不足四個元素的子序列,歸爲一個子序列。
第三次歸併,將每八個元素歸併爲一個子序列,不足八個元素的歸作一個序列。
第四次歸併,將所有元素歸併爲一個完整的有序序列。
2.示例代碼
對一個長度爲N的序列由小到大進行排列,序列需要進行歸併的次數爲
public class MergeSort {
public static void main(String[] args) {
int[] array = { 4, 7, 8, 6, 5, 9, 3, 0, 2, 1 };
MergeSort.sort(array);
System.out.println("排序後數組:" + Arrays.toString(array));
}
public static void sort(int[] a) {
int i, j;
int low, mid, high;// 數組索引的低、中、高
int gap;// 數組索引間隔
int time = (int) Math.ceil(Math.log(a.length) / Math.log(2));// 計算數組的合併次數
for (i = 1; i <= time; i++) {
gap = (int) (Math.pow(2, i) - 1);// 合併後相鄰子序列的步長
// 遍歷每個合併後的數組
for (j = 0; j + gap < a.length; j = j + gap + 1) {
low = j;// 當前遍歷數組的索引最低值
high = j + gap;// 當前遍歷數組的索引最大值
mid = (int) Math.floor((high + low) / 2);// 當前遍歷數組的索引中間值
merge(a, low, mid, high);
}
// 將剩下的數組進行歸併排序
if (j + gap >= a.length) {
low = j;// 當前遍歷數組的索引最低值
high = a.length - 1;
// 當前遍歷數組的索引中間值,j+gap代表理論上的最大索引
mid = (int) Math.floor(((j + gap) + low) / 2);
merge(a, low, mid, high);
}
System.out.println(Arrays.toString(a)+":"+i);
}
}
/**
* 數組合並後,low爲合併前第一段數組的最小角標,mid+1位合併前第二段數組的最小角標。
* 同時low爲合併後數組的最小角標,high爲合併後數組的最大角標
*/
private static void merge(int[] a, int low, int mid, int high) {
if (low < high) {
int[] temp = new int[high - low + 1];// 創建一個臨時數組
int first = low;
int second = mid + 1;
// 掃描兩端序列,取最小值放入臨時數組中
for (int i = 0; i < temp.length; i++) {
if (first <= mid && second <= high) {
// 取出兩個數組中較小的數放入臨時數組中,其中一個數組中取出較小的數后角標後移,沒有取出較小數的數組角標不變
temp[i] = a[first] < a[second] ? a[first++] : a[second++];
} else if (first <= mid) {// 若第一段數組沒有遍歷完,將剩餘的數添加到臨時數組中
temp[i] = a[first++];
} else if (second <= high) {// 若第二段數組沒有遍歷完,將剩餘的數添加到臨時數組中
temp[i] = a[second++];
}
}
// 將臨時數組中值替換到原始數組中
for (int i = 0; i < temp.length; i++, low++) {
a[low] = temp[i];
}
}
}
}
3.算法分析
時間複雜度:
歸併排序的序列需要進行
算法穩定性:
相同元素之間不會發生位置交換,歸併排序是一種穩定的排序算法。