思想:
归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法。
该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列。
即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
上代码:
package Data.Structure.sort.Merge;
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args) {
int A[] = {8, 4, 5, 7, 1, 3, 6, 2};
int temp[] = new int[A.length];//归并排序需要一个额外的空间
mergeSort(A, temp, 0, A.length - 1);
System.out.println(Arrays.toString(A));
}
//归并排序
public static void mergeSort(int[] A, int[] temp, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;//中间索引
mergeSort(A, temp, left, mid);//向左进行递归分解
mergeSort(A, temp, mid + 1, right);//向右进行递归分解
//合并
merge(A, temp, left, mid, right);
}
}
/**
* 合并这块 重要
*
* @param A 排序的原始数组
* @param temp 做中转的数组
* @param left 左边有序序列的初始索引
* @param mid 中间索引
* @param right 右边的索引
*/
public static void merge(int[] A, int[] temp, int left, int mid, int right) {
int i = left;//初始化i,左边的有序序列的初始索引
int j = mid + 1;//初始化j,右边的有序序列的初始索引
int t = 0;//指向temp数组的当前索引
/**
* 第一步:先把左右两边数据按照规则填充到temp数组,直到左右两边
* 有序序列有一边处理完毕
*/
while (i <= mid && j <= right) {//继续
if (A[i] <= A[j]) {
//如果左边有序序列的当前元素<= 右边有序序列的当前元素
//即将左边的当前元素填充到temp数组中去 然后t++ i++
temp[t++] = A[i++];
} else {
temp[t++] = A[j++];
}
}
//退出上面这个while循环的话 要么不满足i <= mid 或者不满足j <= right
/**
* 第二步:把有剩余数据的一方的数据全部填充到temp中
*/
while (i <= mid) {//左边的有序序列还有剩余的数据,就全部填充到temp中去
temp[t++] = A[i++];
}
while (j <= right) {//右边的有序序列还有剩余的数据,就全部填充到temp中去
temp[t++] = A[j++];
}
/**
* 第三步:把temp数组元素拷贝到A中去
*/
t = 0;
int tempLeft = left;
while (tempLeft <= right) {
//第一次合并tempLeft=0,right=1 第二次合并 tempLeft=2,right=3
//。。。。最后一次合并 tempLeft=0,right=7
A[tempLeft++] = temp[t++];
}
// for (t=0,i=left;i<=right;t++,i++){
// A[i]=temp[t];
// }
}
}
结束语:
路漫漫其修远兮 吾将上下而求索