归并排序
这篇文章将从二叉树的角度理解归并排序。归并排序的本质是采用递归的方式将一个数组分为若干个子数组,直到子数组分为一个个独立的数据的时候,开始进行有序的合并排序。
归并排序的执行流程
①、不断的将当前序列平均分割成2个子序列,直到不能再分割(子序列中只剩一个元素);
②、不断的将2个子序列合并成为一个有序的序列,直到最后合并为一个序列。
对于归并排序的总结思考
先对左右子数组进行排序,然后进行合并(有序,类似于合并有序链表的逻辑),仔细想一想像不像二叉树的后序遍历,将整个数组看作根节点,然后通过中间值进行前后子数组的划分,然后进行依次有序合并。
//对比二叉树的前中后序递归遍历问题与归并排序的递归左右子数组的划分问题
//二叉树的前、中、后序的遍历
public void process(TreeNode root){
if(root == null){
return;
}
//前序遍历的位置
process(root.left);
//中序遍历的位置
process(root.right);
//后序遍历的位置
}
//归并排序左右子数组的划分问题
public void mergeSort(int[] arr, int left, int right){
if(left >= right){
return;
}
//在前序遍历获取到,中间值
int mid = (right-left)/2+left;
//像不像递归左子树部分和右子树部分
mergeSort(arr,left,mid);
mergeSort(arr,mid+1,right);
//在后序遍历进行排序合并
merge(arr,left,mid,right);
}
合并的方法就是采用merge
将左右子数组进行有序的合并
public void merge(int[] arr, int left, int mid, int right){
//开辟一个新的数组,用于做辅助数组,暂时存放有序数据
int[] help = new int[right-left+1];
int index = 0;
int p1 = left;
int p2 = mid+1;
//将左右子数组进行比较,将比较后的数据存放在辅助数组当中。
while(p1 <= mid && p2 <= right){
help[index++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
//右子数组为空,左子数组不为空
while(p1 <= mid){
help[index++] = arr[p1++];
}
//左子数组为空,右子数组不为空
while(p2 <= right){
help[index++] = arr[p2++];
}
//将辅助数组中的数据存储到之前的数组当中
for(int i = 0; i < help.length; i++){
arr[left+i] = help[i];
}
}
完整代码
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
public int[] MySort (int[] arr) {
// write code here
if(arr.length < 2){
return arr;
}
megerSort(arr,0,arr.length-1);
return arr;
}
public void mergeSort(int[] arr, int left, int right){
if(left >= right){
return;
}
//在前序遍历获取到,中间值
int mid = (right-left)/2+left;
//像不像递归左子树部分和右子树部分
mergeSort(arr,left,mid);
mergeSort(arr,mid+1,right);
//在后序遍历进行排序合并
merge(arr,left,mid,right);
}
public void merge(int[] arr, int left, int mid, int right){
int[] help = new int[right-left+1];
int index = 0;
int p1 = left;
int p2 = mid+1;
while(p1 <= mid && p2 <= right){
help[index++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
while(p1 <= mid){
help[index++] = arr[p1++];
}
while(p2 <= right){
help[index++] = arr[p2++];
}
for(int i = 0; i < help.length; i++){
arr[left+i] = help[i];
}
}
}