基本思想
归并排序是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;
算法描述
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
- 重复步骤3直到某一指针到达序列尾
- 将另一序列剩下的所有元素直接复制到合并序列尾
演示
代码实现
public static void sort(int[] array, int l, int r, int[] tempArray) {
if (l < r) {
int mid = (l + r) / 2;
sort(array, l, mid, tempArray);
sort(array, mid + 1, r, tempArray);
merge(array, l, mid, r, tempArray);
}
}
/**
*
* @param array 待排序数组
* @param left 待排序数组最左端下标
* @param mid
* @param right 待排序数组最右端下标
* @param tempArray 临时数组
*/
public static void merge(int[] array, int left, int mid, int right, int[] tempArray) {
int l = left;
int r = mid + 1;
int t = 0;// tempArray填充数据的坐标
//比较大小将比较小的数据放到tempArray中
while (l <= mid && r <= right) {
if (array[l] <= array[r]) {
tempArray[t] = array[l];
t = t + 1;
l = l + 1;
} else {
tempArray[t] = array[r];
t = t + 1;
r = r + 1;
}
}
//将不需要比较的直接复制到tempArray中
while (l <= mid) {
tempArray[t] = array[l];
t = t + 1;
l = l + 1;
}
while (r <= right) {
tempArray[t] = array[r];
t = t + 1;
r = r + 1;
}
//将tempArray中的数据复制到array中
int k = 0;
for (int i = left; i <= right; i++) {
array[i] = tempArray[k];
k++;
}
}
时间复杂度
归并排序每次会把当前的序列一分为二,然后两部分各自排好序之后再合并,这个就像是一颗二叉树,每一层总的计算量是O(n)的,总的层数是O(logn)的,所以总的复杂度是O(nlogn)
最佳情况:O(nlogn)
最坏情况:O(nlogn)
平均情况:O(nlogn)
空间复杂度
需要与待排序元素同样大小的空间用于临时存放数据,所以空间复杂度是O(n)
优点与缺点
- 对两个已有序的序列归并,优势明显,时间复杂度都是O(nlog2n)
- 不适用于数据节点数据量大的数据
测试记录
待补充
源码
java.util.Arrays中使用到了归并排序