概念(实现思想)
百度解释:归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
个人理解:采用分治法。将数组分成两半,对分开的部分进行排序。然后利用辅助数组进行合并,称之为归并排序。
实现原理
归并操作的工作原理如下:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置;
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
重复步骤3直到某一指针超出序列尾;
将另一序列剩下的所有元素直接复制到合并序列尾。
举例
原始序列为{4,2,5,3,1,6}
经过以下步骤:
排序后的序列为{1,2,3,4,5,6}
代码实现
/**
* 对总数组进行排序
* @param arr
*/
public static void mergesort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
sortProcess(arr, 0, arr.length - 1);
}
/**
* 对分开的两个数组进行排序
* @param arr
* @param L
* @param R
*/
public static void sortProcess(int[] arr, int L, int R) {
if (L == R) {
return;
}
int mid = L + (R - L) / 2;
sortProcess(arr, L, mid);
sortProcess(arr, mid + 1, R);
merge(arr, L, mid, R);
}
/**
* 进行交换
* @param arr
* @param L
* @param m
* @param R
*/
public static void merge(int[] arr, int L, int m, int R) {
//辅助数组,长度为原数组的长度
int[] help = new int[R - L + 1];
int i = 0;
int p1 = L;
int p2 = m + 1;
// 比较p1、p2的值(将值小的填入辅助数组,并移动指针)
while (p1 <= m && p2 <= R) {
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
// 此时p2已经填充完毕,将剩余的p1数组中的元素填充至辅助数组
while (p1 <= m) {
help[i++] = arr[p1++];
}
// 与上面的条件相同,只会触发一个
while (p2 <= R) {
help[i++] = arr[p2++];
}
//将辅助数组的值填入到原数组
for (i = 0; i < help.length; i++) {
arr[L + i] = help[i];
}
}
总结
归并排序和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(n log n)的时间复杂度。代价是需要额外的内存空间。