1.分治
分治就是"分而治之",就是把一个复杂的问题进行不断的拆分,拆成两个或者若干个相同或者相似的子问题,然后再把子问题分成更小的子问题.. 最后分到子问题可以单独求解
2.归并排序
分:首先将一个无序的数组拆分成若干部分(在此处的思路就是拆分成单个数为止)
治:然后将分离的数进行合并(合并的过程中进行比较排序),最后得到两个有序的序列
最后再通过一些思路将两个有序序列进行合并,得到最终结果
3.图示(图片来自 图解java算法和数据结构)
4.举个栗子
4-1:如何进行数据的拆分(采用递归的方式)
4-2:如何进行数据的合并(在这里手写了最后一次的过程..)
扫描二维码关注公众号,回复:
9322833 查看本文章
看波代码,逻辑其实挺简单,但是需要注意标志位的移动
/**
* arr表示待排序的数组
* left表示左边有序序列的初始索引
* mid表示中间索引
* right表示右边索引
* temp表示临时数组,起到中转的作用
*
*
*/
public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left;//初始化i,表示左边有序序列的初始索引
int j = mid + 1;//初始化j,表示右边有序序列的初始索引
int t = 0;//指向temp数组的当前索引
//1.
//先把左右两边(已经是有序的)的数据按照规则填充到temp中,
//直到左右两边有序序列,有一边处理完毕为止
while (i <= mid && j <= right) {
//如果左边有序序列的当前元素小于或者等于右边的当前元素,然后将该数据填充入temp中
if (arr[i] <= arr[j]) {
temp[t] = arr[i];
t++;
i++;
} else {
//反之将右边的数据填充入temp数组中
temp[t] = arr[j];
t++;
j++;
}
}
//此时一边已经走完 另一边还在继续行进
//2.
//把有剩余数据的一边的数据依次全部填充到temp去
while (i <= mid) {//说明坐标的有序序列还是有剩余的,将左边数据进行填充
temp[t] = arr[i];
t++;
i++;
}
while (j <= right) {//说明坐标的有序序列还是有剩余的,将右边数据进行填充
temp[t] = arr[j];
j++;
i++;
}
//3.
//将temp的数组的元素拷贝到arr
t=0;
int tempLeft=left;
int tempRight=right;
while(tempLeft<=tempRight){
arr[tempLeft]=temp[t];
t++;
tempLeft++;
}
}
4-3:如何进行数据的拆分(递归)
//归并排序(递归)
public static void mergeSort(int[] arr, int left, int right, int[] 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);
}
}
4-4:调用主方法
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("归并排序后" + Arrays.toString(arr));
}
4-5:测试结果:
4-6:完整代码:
https://github.com/Lzin/sort_algor/tree/master/src/com/liz/merge_sort