一、基本思想
归并排序是利用归并的思想实现排序的方法,该算法采用经典的分治策略
1.分:即将问题分成一些小问题 分阶段可以理解为递归拆分子序列的过程
2.治:将分的阶段得到的各答案修补在一起
二、算法分析
把长度为n的输入序列分成两个长度为n/2的子序列;
对这两个子序列分别采用归并排序;
将两个排序好的子序列合并成一个最终的排序序列。
合并次数为:n - 1 所以时间复杂度为o(n) 线性
三、画图分析
四、代码实现
public class MergeSort{
public static void main(String[] args){
int arr[] = {8,4,123,123,1,3,4,2,3,5};
int temp[] = new int[arr.length];//归并排序需要一个额外空间
mergeSort(arr,0,arr.length - 1,temp);
}
/*合并方法
arr 排列的原始数组
left 左边有序序列的初始索引
mid 中间索引(中间值) mid + 1就是右边序列的第一个位置
right 右边索引
temp 做中转的数组,(我们在过程中会将排好的数组放进去暂存,然后再释放)*/
public static void merge(int[] arr, int left, int mid, int right, int[] temp){
int i = left;//定义i接收最左侧下标
int j = mid + 1;//定义j接收mid + 1位置下标
int t = 0;//定义temp数组初始下标
//只要i小于中间位置下标,j小于最右侧下标,循环就继续
while(i <= mid && j <= right){
if(arr[i] <= arr[j]){//只要左侧数组i下标值小于右侧数组j下标值
//将左侧数组i下标值放入temp数组
//i和t同时++
temp[t] = arr[i];
i++;
t++;
}else{
//否则说明右侧j下标值小于左侧i下标值
//将左侧数组j下标值放入temp数组
//j和t同时++
temp[t] = arr[j];
j++;
t++;
}
}
//为了防止出现左侧数组没有排完而右侧数组已经全部放入temp数组的情况
while(i <= mid){
temp[t] = arr[i];
i++;
t++;
}
//为了防止出现右侧数组没有排完而左侧数组已经全部放入temp数组的情况
while(j <= right){
temp[t] = arr[j];
t++;
j++;
}
//把temp数组的元素拷贝到arr
//注意不是每一次都拷贝8个(最多的时候一次拷贝8个)
t = 0;
int templeft = left;
while(templeft <= right){
arr[templeft] = temp[t];
t += 1;
templeft += 1;
}
}
//分+合的方法
public static void mergeSort(int[] arr,int left,int right,int[] temp){
if(left < right){
int mid = (left + right)/2;
mergeSort(arr, left, mid, temp);
mergeSort(arr, mid + 1, right, temp);
merge(arr, left, mid, right, temp);
}
}
}