归并排序(想深入理解很难,但是掌握不是很难)
**思路分析:**本质的问题也就是一个递归,对数据进行一个拆分,分而治之,先进行拆分,拆分到每个序列中只有一个数的时候,进行归并,两个两个进行比较合为一个序列,再对每个合并的序列进行比较
- 初始化几个数值,
- 先把左右两边的有序的数据按照规则填充到temp数组,直到左右两边的有序序列,有一边处理完毕即可
- 把所有的剩余数据的一边的数据依次填充到temp
- 将temp数组的元素重新拷贝到arr
import java.util.Arrays;
/**
* @author 是狸猫啊!
* @Version 1.0
* 演示归并排序
*/
public class MergeSort {
public static void main(String[] args) {
int[] arr = {8, 4, 5, 7, 1, 3, 6, 2};
int[] temp = new int[arr.length];
MergeSort(arr, 0, arr.length - 1, temp);
System.out.println("arr=" + Arrays.toString(arr));
}
//演示分的方法
public static void MergeSort(int[] arr, int left, int right, int[] temp) {
int l = left;
int r = right;
int mid = (l + r) / 2;
if (l < r){
//对左边进行的数组进行递归分解
MergeSort(arr,l,mid,temp);
//对右面的数组进行分解
MergeSort(arr,mid + 1,r,temp);
merge(arr,left,mid,right,temp);
}
// if (left < right) {
// int mid = (left + right) / 2;
// MergeSort(arr,left,mid,temp);
// MergeSort(arr,mid+1,right,temp);
// merge(arr,left,mid,right,temp);
//
// }
}
/**
* @param arr 原始数组
* @param left 左边有序序列的初始索引
* @param mid 中间索引
* @param right 右边的初始索引
* @param temp 临时的变量
*/
public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left;
int j = mid + 1;//右边数组的第一个值的数组下标
int t = 0;//临时数组的索引
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[t] = arr[i];
t++;
i++;
} else {
temp[t] = arr[j];
t++;
j++;
}
}
//这下将左边的值全部填充到数组里面
while (i <= mid) {
temp[t] = arr[i];
t++;
i++;
}
while (j <= right) {
temp[t] = arr[j];
t++;
j++;
}
//这里呢!需要将指针重新归位 方便后续的赋值
int templeft = left;
t = 0;
//最后进行数组重新赋值
while (templeft <= right) {
arr[templeft] = temp[t];
templeft++;
t++;
}
}
}
和快排的速度几乎是一样的