基本思想
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
总的来说,是先将数组拆分,再合并;每次拆分,在原来的基础上,将数组拆分为两份,若可继续拆分;则继续拆分,直到无法拆分;再将拆分的数组排序并合并
例如:【1,5,4,3,7,6,8,2,9, 10】----> 【1,5,4,3,7】【6,8,2,9,10】
—>【1,5,4】【3,7】【6,8,2】【9,10】—>【1,5】【4】【3,7】【6,8】【2】【9,10】
—>【1,4,5】【3,7】【2,6,8】【9,10】—>【1,3,4,5,7】【2,6,8,9,10】
—>【1,2,3,4,5,6,7,8,9,10】
流程图
JAVA编码实现
/**
* 归并排序
*/
public class MergeSort extends Sort {
public static void main(String[] args) {
// DataCheck.checkArithmetic(new MergeSort());
MergeSort is = new MergeSort();
int[] arr = is.sort(new int[]{1, 52, 6, 23, 5, 4, 3, 7, 15 ,17});
is.print(arr);
System.out.println();
}
@Override
public int[] sort(int[] arr) {
return sortOne(arr, 0, arr.length - 1);
// return sortBase(arr);
}
/**
* 归并排序
* @param arr 需排序的数组
* @param left 排序左下标【开始坐标】
* @param right 排序右下标【结束坐标】
* @return
*/
public int[] sortOne(int[] arr, int left, int right){
if(left == right){
return arr;
}
//获取
int mid = left + (right - left) / 2;
// 排序左边数组
sortOne(arr, left, mid);
//排序右边数组
sortOne(arr, mid + 1, right);
//将排序好的左边数组 与 右边数组合并排序
return merge(arr, left, mid + 1, right);
}
/**
* 将一个连续的 左右两个有序数组的连接体排序,例:【1, 3, 6, 11, 5, 7, 9, 18]
* @param arr 数组
* @param leftPtr 左数组开始索引 [0]
* @param rightPtr 右数组开始索引[4]
* @param rightBound 右数组结束索引【包含】[7]
*/
public int[] merge(int[] arr, int leftPtr, int rightPtr, int rightBound){
//左数组结束索引
int mid = rightPtr -1;
int[] temp = new int[rightBound - leftPtr + 1];
int i = leftPtr; int j = rightPtr, k = 0;
while(i <= mid && j <= rightBound){
temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];
}
while(i <= mid){
temp[k++] = arr[i++];
}
while(j <= rightBound){
temp[k++] = arr[j++];
}
for(int m = 0; m < temp.length; m++){
arr[leftPtr + m] = temp[m];
}
return arr;
}
//
public int[] sortBase(int[] arr){
if(arr.length == 2){
if(arr[0] > arr[1]){
swap(arr, 0, 1);
}
return arr;
}else if(arr.length <= 1){
return arr;
}
int num = arr.length / 2;
int[] left = new int[num];
int[] right = new int[arr.length-num];
System.arraycopy(arr, 0, left, 0, num);
System.arraycopy(arr, num, right, 0, arr.length-num);
return mergeOrderly(sortBase(left), sortBase((right)));
}
/**
* 将两个有序的数组 进行有序的合并
* @param arrLeft
* @param arrRight
* @return
*/
public int[] mergeOrderly(int[] arrLeft, int[] arrRight){
int[] arr = new int[arrLeft.length + arrRight.length];
int left = 0, right = 0;
for(int i = 0; i < arr.length; i++){
if(left >= arrLeft.length || right >= arrRight.length){
arr[i] = left >= arrLeft.length ? arrRight[right++] : arrLeft[left++];
continue;
}
arr[i] = arrLeft[left] <= arrRight[right] ? arrLeft[left++] : arrRight[right++];
}
return arr;
}
//替换
public void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//打印int数组
public void print(int[] arr){
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
}
}