一、利用分治算法的思想,假设下标为0~7,分治过程如下:
[0~7] 全部无序
/ \
[0~3] [4~7] 子序列内无序
/ \ / \
[0~1] [2~3] [4~5] [6~7] 子序列内无序
/ \ / \ / \ / \
0 1 2 3 4 5 6 7 子序列内有序
\ / \ / \ / \ /
[0~1] [2~3] [4~5] [6~7] 子序列内有序
\ / \ /
[0~3] [4~7] 子序列内有序
\ /
[0~7] 全部有序
二、归并排序算法如下,其中数组r保存排序后的结果,s为待排序源数据数组:
public static void mergeSort(int [] r, int [] s, int begin, int end){
if(begin == end){
return;
}
int middle = (begin + end)/2;
mergeSort(r, s, begin, middle);
mergeSort(r,s, middle + 1, end);
merge(r, s, begin, middle, end);
}
其中搜集排序结果的函数merge如下:
public static void merge(int [] r, int [] s, int begin, int middle, int end){
int i = begin;
int j = middle + 1;
int k = begin;
while(i <= middle && j <= end){
if(s[i] <= s[j]){
r[k++] = s[i++];
}else{
r[k++] = s[j++];
}
}
if(i <= middle){
for(; i <= middle; i++){
r[k++] = s[i];
}
}
if(j <= end){
for(; j <= end; j++){
r[k++] = s[j];
}
}
//把有序序列r[begin]~r[end],回写到s[begin]~s[end],这一步很重要
for(int l = begin; l <= end; l++){
s[l] = r[l];
}
}
三、完整的测试程序如下:
package mergeSort;
public class MergeSort {
public static int [] s = new int[]{5,11,6,4,1,10,9,8,7};
public static int [] r = new int[s.length];
public static void main(String[] args) {
printArr(s, "排序前: ");
mergeSort(r,s,0,s.length - 1);//调用归并排序
printArr(r, "排序后: ");//打印排序结果
}
//执行归并排序
public static void mergeSort(int [] r, int [] s, int begin, int end){
if(begin == end){
return;
}
int middle = (begin + end)/2;
mergeSort(r, s, begin, middle);
mergeSort(r,s, middle + 1, end);
merge(r, s, begin, middle, end);
}
//把两个无序的子序列s[begin]~s[middle]和子序列s[middle + 1]~s[end]合并为一个有序序列r[begin]~r[end],然后回写到s[begin]~s[end]
public static void merge(int [] r, int [] s, int begin, int middle, int end){
int i = begin;
int j = middle + 1;
int k = begin;
while(i <= middle && j <= end){
if(s[i] <= s[j]){
r[k++] = s[i++];
}else{
r[k++] = s[j++];
}
}
if(i <= middle){
for(; i <= middle; i++){
r[k++] = s[i];
}
}
if(j <= end){
for(; j <= end; j++){
r[k++] = s[j];
}
}
//把有序序列r[begin]~r[end],回写到s[begin]~s[end],这一步很重要
for(int l = begin; l <= end; l++){
s[l] = r[l];
}
}
public static void printArr(int [] arr, String flag){
System.out.print(flag);
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
四、测试程序运行结果如下:
排序前: 5 11 6 4 1 10 9 8 7
排序后: 1 4 5 6 7 8 9 10 11