思路:将数组分为不越界条件下的无限小段,然后不断迭代每一个小段数组,进行merge排序, 排序时使用一个辅助数组来存储当前小段数组的有序结果,再讲辅助数组中的结果存入到结果数组中 不断迭代这个过程最终实现归并排序
//question: 设计一个方法,将一个数组排序
public static void process(int[] arr, int L, int R) {
//使用递归的方法 先将数组分为很多个有限范围内的小段 然后在小段内进行元素的排序 之后将排完序的结果存入到原数组中
//递归出口 如果左右相等时 ,直接退出
if (L == R) {
return;
}
//找到中间值以进行左右分区
int mid = L + ((R - L) >> 1); // int mid = L + ((R - L)) / 2;
//递归进行左边的分区
process(arr, L, mid);
//递归进行右边的分区
process(arr, mid + 1, R);
//进行区内的排序 调用方法进行操作
merge(arr, L, mid, R);
}
//排序
//设计一个方法,用来给数组进行排序,怎么排??
/*
参数: 数组 左边起始位置 右边起始位置
需要一个额外的空间来临时存储排序的结果 多大?? 根据传进来的左边和右边位置就可以计算出来了
两个指针一起找,通过两个指针所指向的值的大小的比对,来将小的先存入到数组中,从而实现较大的效率
指针一: P1指向最左边 p1等于谁?? 等于L 因为当前区从L开始
指针二: P2指向中间位置的后一个元素
两个指针将这个数组分成了左右两块区域 两个指针的移动来将这两块区域的值进行排序
开始循环:
分为三种情况:
1.p1和p2都不越界
循环条件?? p1 不能超过Mid吧 p2不能超过R吧
怎么操作:
通过比对arr中当前P1位置的值和P2位置的值谁小,小的先放入help数组中 实现排序
2.p1越界,p2不越界
循环条件?? p1肯定不用了 直接将p2的值放入到数组中就可以
操作:直接将p2的值放入到数组中就可以
3.p2越界,p1不越界
循环条件?? p2肯定不用了 直接将p1的值放入到数组中就可以
操作:直接将p1的值放入到数组中就可以
循环完成干什么??
肯定要将help数组中的有序的值放入到原数组中
怎么放?索引位置怎么对应? 从L的位置上开始放 使用一个变量控制移动
*/
public static void merge(int[] arr, int L, int M, int R) {
int[] help = new int[R - L + 1];
//help的索引位置
int i = 0;
int p1 = L;
int p2 = M + 1;
//情况一:都不越界
while (p1 <= M && p2 <= R) {
//使用三目运算符
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
//情况二:p1越界 p2不越界
while (p2 <= R && p1 > M) {
help[i++] = arr[p2++];
}
//情况三:p1不越界 p2越界
while (p1 <= M && p2 > R) {
help[i++] = arr[p1++];
}
for (i = 0; i < help.length; i++) {
arr[L + i] = help[i];
}
}