活动地址:CSDN21天学习挑战赛
一、merge
在归并排序之前,我们先了解merge过程
merge的原理是谁小拷贝谁
通过传入的中间下标m(mid)把数组划分成左右两部分,p1为左部分的开始坐标,p2为右部分的开始坐标,定义一个help数组,index为开始坐标
比较p1和p2的值,如果p1小则拷贝p1到help[index],反之拷贝p2,直到p1或者p2越界,再单独拷贝剩下的数,最后将help拷贝回原数组
谁小拷贝谁,拷贝1
拷贝2
谁小拷贝谁,直到把左边或者右边拷完,再单独拷贝一边
public void merge(int[] nums,int l,int m,int r){
if(l==r){
return;
}
int[] help=new int[r-l+1];
int p1=l;
int p2=m+1;
int index=0;
//谁小拷贝谁
while(p1<=m&&p2<=r){
help[index++]=nums[p1]<=nums[p2]?nums[p1++]:nums[p2++];
}
while(p1<=m){
help[index++]=nums[p1++];
}
while(p2<=r){
help[index++]=nums[p2++];
}
for(int i=0;i<help.length;i++){
nums[l+i]=help[i];
}
}
二、归并排序
知道了merge的步骤,那么我们就可以开始归并排序了
在递归的过程中,不断的把左右两部分排好序,最后将整体排序
public static void mergeSort1(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
process(arr, 0, arr.length - 1);
}
public static void process(int[] arr, int L, int R) {
if (L == R) {
return;
}
int mid = L + ((R - L) >> 1);
process(arr, L, mid);
process(arr, mid + 1, R);
merge(arr, L, mid, R);
}
public void merge(int[] nums,int l,int m,int r){
if(l==r){
return;
}
int[] help=new int[r-l+1];
int p1=l;
int p2=m+1;
int index=0;
//谁小拷贝谁
while(p1<=m&&p2<=r){
help[index++]=nums[p1]<=nums[p2]?nums[p1++]:nums[p2++];
}
while(p1<=m){
help[index++]=nums[p1++];
}
while(p2<=r){
help[index++]=nums[p2++];
}
for(int i=0;i<help.length;i++){
nums[l+i]=help[i];
}
}