归并排序
利用分治策略,将大问题分为小问题递归进行求解。
基本思想:
合并相邻有序子序列的过程
思路分析:
一般来说先写一个分解的函数,再写一个合并的函数。
分解函数
- 判断是否left<right,如果是的话进行计算mid操作之后,完成左边的分解和右边的分解。
- 在完成分解之后进行一次合并
合并函数
- 把左右两边的数据按照规则填充到temp数组,直到有一边序列填充完毕了。
- i<mid,j<right的前提下:左右进行比较,小的移动到temp中
- 移动之后,被移动的数组中的索引加一,temp的索引加一
- 把有剩余的序列全部填充到temp数组中。
- 将temp数组拷贝到原数组中
- 因为每次传入的数组并不是最后一个完整的数组,所以创立一个临时left,因为之前移动过temp的指针,所以这里也要把temp置为0。当left小于right,依次将temp值移入arr中。
代码实现:
package com.sortAlgorithm;
import java.util.Arrays;
public class mergeSort {
public static void main(String[] args) {
int[] arr = {8, 4, 5, 7, 1, 3, 6, 2};
int[] temp = {0, 0, 0, 0, 0, 0, 0, 0};
mergeSort mergeSort = new mergeSort();
mergeSort.divide(arr, 0, 7, temp);
System.out.println("排序后:" + Arrays.toString(arr));
}
public void divide(int[] arr, int left, int right, int[] temp) {
int mid = (left + right) / 2;
if (left < right) {
System.out.println("分组中···");
divide(arr, left, mid, temp);
divide(arr, mid + 1, right, temp);
merge(arr, left, right, mid, temp);
}
}
public void merge(int[] arr, int left, int right, int mid, int[] temp) {
//把左右两边的数据按照规则填充到temp数组,直到有一边序列填充完毕了。
//
//1. 左右进行比较,小的移动到temp中
//2. 移动之后,被移动的数组中的索引加一,temp的索引加一
int i = left;
int j = mid + 1;
int tempIndex = 0;
while (i <= mid && j <= right) {
if (arr[i] < arr[j]) {
System.out.println("右侧大于左侧!移动右侧进入temp数组中");
temp[tempIndex] = arr[i];
tempIndex++;
i++;
} else {
System.out.println("左侧大于右侧!移动左侧进入temp数组中");
temp[tempIndex] = arr[j];
tempIndex++;
j++;
}
//把有剩余的序列全部填充到temp数组中。
while (j <= right) {
System.out.println("加入右侧剩余数字中···");
temp[tempIndex] = arr[j];
tempIndex++;
j++;
}
while (i <= mid) {
System.out.println("加入左侧剩余数字中···");
temp[tempIndex] = arr[i];
tempIndex++;
i++;
}
//将temp数组拷贝到原数组中
//1. 创立一个临时left,当left小于right,依次将temp值移入arr中。
tempIndex = 0;
int templeft = left;
while (templeft <= right) {
arr[templeft] = temp[tempIndex];
tempIndex++;
templeft++;
}
}
}
}