归并排序算法体现了分而治之的思想,将 大的问题切分为小的部分,然后将切分的问题得到的答案统一到一起,这就是分治思想!!
归并排序的过程大概如图所示
拆分整体十分像完全二叉树 分的过程就是递归遍历二叉树 时间复杂度 为O(logN)
合并的操作时间复杂度为 O(N) 总体时间复杂度为 O (NlogN) 并且最坏时间复杂度和最好数据复杂度都是O (NlogN)
.递归实现归并排序java代码
if (start < end) {
int mid = (start + end) / 2;
//左子序列有序
merge(a, start, mid);
//右子序列有序
merge(a, mid + 1, end);
//合并有序序列
mort(a, start, mid, end);
}
}
//子序列合并
public static void mort(int[] ints, int left, int mid, int right) {
//申请合并空间
int[] temp = new int[ints.length];
//指针分别指向两个序列的开始位置
//i1 指向序列开始 i2指向序列中央 将序列分为两个子序列
//i3 只想合并空间开始位置
int i1 = left, i2 = mid + 1, i3 = left;
while (i1 <= mid && i2 <= right) {
//比较两个序列指针所在位置大小
if (ints[i1] < ints[i2]) {
//将较小的放入合并空间 后 移动指针到下一位置
temp[i3++] = ints[i1++];
} else {
temp[i3++] = ints[i2++];
}
}
//将子序列剩余的数字放入合并空间
while (i1 <= mid) {
temp[i3++] = ints[i1++];
}
while (i2 <= right) {
temp[i3++] = ints[i2++];
}
//将合并空间的数回填至序列
for (int i = left; i <= right; i++) {
ints[i] = temp[i];
}
}
归并排序算法是稳定排序 (即在排序过程中大小相同的元素能够保持排序前的顺序,3212升序排序结果是1223,排序前后两个2的顺序不变,这一点在某些场景下至关重要) 他利用了完全二叉树的特性,十分的高效。 归并排序算法是比较排序算法(快排,堆排序,希尔排序)中效率最高的,比较次数最少的,但是他也有自己的缺点,归并排序需要O(n)的辅助空间而快排和堆排分别需要O(logn)和O(1)的辅助空间 在java中的泛型比较类库中的sort方法使用的就是归并排序,因为在java中对象的比较代价是较大的(根据 compareable 接口中 compareto方法进行比较)而对象的移动代价较小,本质上对象移动移动的是引用,而归并排序是所有排序中比较次数最少的 java.util.Arrays.sort(T[] arr)使用的是归并排序 java.util.Arrays.sort(int[] arr) 使用的是快速排序
注:在jdk1.7后使用了TIMSort替代了归并排序, TIMSort 排序集合了归并排序和插入排序的特点,对归并和插入进行了优化: 1 : 在归并排序时,不在切分到单个元素; 2 :在插入排序时 ,使用了二分查找;