归并排序
核心:先拆后合
不多逼逼,直接上图
看完图,肯定已经明白一大部分了。
//该方法是:拆 ------- arr:待排数组,left:第一个元素下标,right:最后一个元素下标,temp:临时数组
public static void divide(int[] arr,int left,int right,int[] temp){
//如果不止一个元素就拆
if (left < right){
//往中间一刀切
int mid = (left+right)/2;
//左边一半
divide(arr,left,mid,temp);
//右边一半
divide(arr,mid+1,right,temp);
//最后合并
merge(arr,left,mid,right,temp);
}
}
//该方法是 合并
public static void merge(int[] arr,int left,int mid,int right,int[] temp){
int l = left;//左半部分的起始下标
int m = mid+1;//右半部分的起始下标
int t= 0 ;//计数,标志temp当前的下标位置
//步骤1:把左右半部分排好序,并且放入临时数组中;
//左半部分的起始位置不能超过左半部分的重点位置,右半部分的起始位置不能超过右半部分的重点位置,
while(l<=mid && m<=right){
if (arr[l]<=arr[m]){ //如果左半部分的当前元素小于等于右半部分的当前元素
temp[t]=arr[l];//将左半部分的当前元素 赋值 给临时数组
l++; //继续往后比较
t++;
}
else {//反之,将右半部分的当前元素 赋值 给临时数组
temp[t]=arr[m];
m++; //继续往后比较
t++;
}
}
//步骤2:下面的两个while是解决: 左半部分或者右半部分还有一些元素没有放入临时数组中
while (l<=mid){
temp[t] = arr[l];
l++;
t++;
}
while (m<=right){
temp[t] = arr[m];
m++;
t++;
}
//步骤3: 把临时数组里的元素,全部覆盖到原数组中
t=0;
int tempLeft=left;
while (tempLeft<=right){
arr[tempLeft]=temp[t];
tempLeft++;
t++;
}
}