前言
最近在学数据结构与算法,在此做一下记录,方便时不时复习一下。如果有什么做得不对的地方,恳请指出,万分感谢。
简述
归并排序是建立在归并操作上的一种有效的排序算法,是采用分治法的一个非常典型的应用。
基本思想是对于给定的一种数组,利用递归与分治技术将数据划分成为越来越小的半子表,在对半子表排序后,再用递归方法将排序好的半子表合并成为越来越大的有序序列。有时候为了提升性能,会在半子表的个数小于某个数(比如15)的情况下,对半子表的排序采用其他排序算法,比如插入排序。因为我这里是将两个有序表合并成为一个有序表,所以也成为2-路归并,与之对应的还有多路归并。
步骤
1.拆分序列,成为越来越小的半子表。
2.对半子表排序后使用递归方法逐步合并最后返回整个排序好的数组。(如果不理解的话结合图示会好一些)
图示
代码
public class MergeSort {
public final static int[] DATA = {1,6,7,2,4,5,9,8};
public static void main(String[] args) {
printArray(DATA);
System.out.println("===========================");
printArray(sort(DATA));
}
public static int[] sort(int[] arrays) {
if (arrays.length < 2) return arrays;
/**
* 拆分过程
*/
int midIndex = arrays.length / 2;
int[] left = Arrays.copyOfRange(arrays,0,midIndex);
int[] right = Arrays.copyOfRange(arrays,midIndex,arrays.length);
return Merge(sort(left),sort(right));
}
/**
* 合并过程
* @param left 左数组
* @param right 右数组
* @return 返回合并排序好的数组
*/
public static int[] Merge(int[] left,int[] right) {
int[] result = new int[left.length + right.length];
for (int index = 0,leftIndex = 0,rightIndex = 0; index < result.length; index++) {
if (leftIndex >= left.length) {//当左边数组的索引大于或等于左边数组长度时,就将右边数组的元素一个接着一个放进result数组中
result[index] = right[rightIndex++];
}else if (rightIndex >= right.length) {//当右边数组的索引大于或等于右边数组长度时,就将左边数组的元素一个接着一个放进result数组中
result[index] = left[leftIndex++];
}else if (left[leftIndex] < right[rightIndex]) {//当左边数组小于右边数组时,谁大放进result数组就造成降序,谁小放进result数组就造成升序
result[index] = right[rightIndex++];
}else {//当左边数组大于右边数组
result[index] = left[leftIndex++];
}
}
return result;
}
public static void printArray(int[] array) {
for (int i:array) {
System.out.print(i + " ");
}
System.out.println("");
}
}
结果