1、概述
归并排序是一种稳定的算法,该算法采用分治法的典型的应用。将已有自序列合并,得到完全有序的序列。即先使每个子序列有序,再使子序列之间有序。然后将两个有序表合成一个有序表,称为二路归并。
归并操作,也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。
如 设有数列{6,202,100,301,38,8,1}
初始状态:6,202,100,301,38,8,1
第一次归并后:{6,202},{100,301},{8,38},{1}
第二次归并后:{6,100,202,301},{1,8,38}
第三次归并后:{1,6,8,38,100,202,301}
2、归并排序算法思路分析
① 申请一个和原数组一样的空间存储排序好的数组
② 定义两个指针,初识位置为两个排好序的起始位置
③ 比较两个指针所指向的元素,选择比较小的放到新的数组空间,往下移动指针
重复步骤③,直到将剩下的数组添加到新数组的结尾
比如初始数组:[24,13,26,1,2,27,38,15]
①分成了两个大小相等的子数组:[24,13,26,1] [2,27,38,15]
②再划分成了四个大小相等的子数组:[24,13] [26,1] [2,27] [38,15]
③此时,left < right 还是成立,再分:[24] [13] [26] [1] [2] [27] [38] [15]
此时,有8个小数组,每个数组都可以视为有序的数组了!!!,每个数组中的left == right,从递归中返回
// 将数组元素分开
mergeSort(arr,left,mid);
mergeSort(arr,mid+1,right);
// 将数组元素比较 排序合并
merge(arr,left,mid,right);
然后——>
merge([24],[13]) 得到 [13,24]
merge([26],[1]) 得到[1,26]
3、代码实现
public class MergeDemo {
public static void main(String[] args) {
int[] array = {7,3,1,4,8,10};
mergeSort(array, 0, 5);
merge(array, 0, 2, 5);
System.out.println(Arrays.toString(array));
}
// 一 对整个数组进行排序
// 先对整个序列进行分组
// 参数 需要排序的数组 数组的第一个位置 数组的最后一个位置 将排序的数组放在新的数组里面
private static void mergeSort(int[] arr,int left,int right) {
// 判断数组
if(left >= right) {
return;
}
// 分治左边和右边 取中间坐标
int mid = (left + right)/2;
// 将数组元素分开
mergeSort(arr,left,mid);
mergeSort(arr,mid+1,right);
// 将数组元素比较 排序合并
merge(arr,left,mid,right);
}
// 合并
private static void merge(int[] arr,int left,int mid,int right) {
// 定义第一个归并序列开始的地方
int s1 = left;
// 定义第二个归并序列开始的地方
int s2 = mid + 1;
// 定义已经归并好的序列元素存放的位子
int[] temp = new int[arr.length];
//定义临时序列的下标 从0开始
int i = 0;
// 向临时序列赋值
while(s1 <= mid && s2 <= right) {
if(arr[s1] <= arr[s2]) {
temp[i++] = arr[s1++];
}else {
temp[i++] = arr[s2++];
}
}
// 如果其中一个序列比较完了 剩下的那组序列就放进去
while(s1 <= mid) {
temp[i++] = arr[s1++];
}
while(s2 <= right) {
temp[i++] = arr[s2++];
}
// 将temp中的元素 复制到 arr序列中
i = 0;
while(left <= right) {
arr[left++] = temp[i++];
}
}
}
4、算法复杂度分析
归并排序的时间复杂度为O(nlogn),具体的计算请访问:https://blog.csdn.net/a1033025319/article/details/88650514
归并排序是所有排序中比较次数最少的,它一开始不断的划分,比较只发生在合并的各个有序的子数组中。
5、总结
归并排序递归方式比较难理解的就是排序合并。一开始比较迷茫,分开的各部分数组怎么排序的呢?是调用这行代码:merge(arr,left,mid,right)。把各个元素合并的时候进行排序。
OK,今天就到这里,喜欢的话点个赞。