各种视频,各种文章上查阅后整理分享。站在巨人的肩膀上摘苹果。
a={1,3,5} b={2,4,6,8,10,12}
两个数组各自有序,想要合并之后有序直接合并无法实现
可以先创建长度与它们加一起一样长的新数组c
首先对比a[0]与b[0] ,b[0]=2 < a[0]=1,将b[0] 的0 放入c[0]的位置
a={3,5} b={4,6,8,10,12}
1 | 2 |
a ,b变成如上,比较3 与4,3<4,
1 | 2 | 3 | 4 |
a={5} b={6,8,10,12}
a ,b变成如上,比较5 与6,5<6,
1 | 2 | 3 | 4 | 5 | 6 |
a={} b={8,10,12}
直接将8,10,12放入c
1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12 |
如果数组是无序的呢,2 4 1 9 3 2 8 7 3 0 5 10
先拆分成2 4 1 9 3 2 | 8 7 3 0 5 10
递归拆分,因为不知道具体需要拆分多少次一直取其长度的二分之一就可以了
第二次拆分成2 4 1 |9 3 2 | 8 7 3 0 5 10
第三次拆分成2 4 |1 |9 3 2 | 8 7 3 0 5 10
第四次拆分成2 |4 |1 |9 3 2 | 8 7 3 0 5 10
2和4 比较 不交换位置, 拿着2 | 4 与 1进行比较 2比较1 , 将1放到2 前面 124
932也是同样的手法,变成 239 ,合并两个有序数组,拿着 124 与 239比较。 第零个与第零个比,1 跟2 比,留 1 ,2 跟2比 一样, 就是 122, 4比3 留3 ,就是1223。4比9 122349.
左边就比较完了,开始霍霍右边,同样的道理就不细说了。
代码:
public class MergerSort {
//第一步
public static void main(String[] args) {
int arr[] = { 2, 568, 34, 46, 9, 23, 89, 43, 572, 684, 783, 543 };
System.out.print(Arrays.toString(arr )+ ",");
mergeSort(arr, 0, arr.length-1);
System.out.println(Arrays.toString(arr));
}
//第三步
//递归分治
public static void mergeSort(int[] arr,int low, int high) {
//结束条件
if(low < high) {
int mid = ((high - low)>>>1) + low;//这么写容易在最大的时候溢出优化办法变相减int mid = (high - low)/2 + low
mergeSort(arr, low, mid);//处理左边
mergeSort(arr, mid+1, high);//右边
merge(arr,low, mid, high);//归并
}
}
//第二步
//哪块开始,哪块分割,哪块结束
public static void merge(int arr[], int low ,int mid ,int high) {
int temp[] = new int[high-low +1];//用于存储临时数组起始数是0长度需要加一
//记录数组一的下标数字
int i = low;
//记录数组2的下标数字
int j = mid+1;
int index = 0;//临时数组下标
//遍历两个数组中小的数字,放入临时数组
while (i <= mid && j <= high) {
if (arr[i] <= arr[j]) {
temp[index] = arr[i];//把小的放入临时数组
i++;//下标后移
index++;
} else {
temp[index] = arr[j];//把小的放入临时数组
j++;//下标后移
index++;
}
}
//长度不一定一致两个数组
//处理多余 j多
while (j <= high) {
temp[index] = arr[j];//多余的直接放入temp
j++;
index++;
}
//i多余
while (i <= mid) {
temp[index] = arr[i];
i++;
index++;
}
for(int k=0; k<temp.length; k++) {
arr[k+low] = temp[k];//把取人家arr数组里面那段补回去毕竟是从low开始取值的
}
}
}