前言
学过递归我们知道,将一个问题划分为许多子问题,通过求解子问题再合并子问题的解即可获得原问题的解。如果说快速排序重在如何划分子序列,,那么归并排序就是重在如何合并子序列。
概述
归并排序算法将数组分为两半,对每部分递归地调用归并排序。在两部分排好序后,对它们进行合并。
基本思路
- 归并排序算法完全依照分治模式
- 1.分解:将n个元素分成各含n/2个元素的子序列
- 2.解决:对两个子序列递归地排序
- 3.合并:合并两个已排好序的子序列
合并方法
- 开辟一个辅助空间,将原数组的元素拷贝进去
- 将此时辅助空间中的元素从中间分为两个子序列
- 在两个子序列的头部(begin,mid+1处)分别设置一个指针
- 左指针处的元素和右指针处的元素进行比较,较小的元素覆盖进原数组
将两个子序列看做两支队伍,两个队伍的队首指针指向的元素进行比较,较小的那一个出队 -
代码实现
/*
* 归并排序
* 原理:
* 归并排序算法完全依照分治模式
* 分解:将n个元素分成各含n/2个元素的子序列
* 解决:对两个子序列递归地排序
* 合并:合并两个已排好序的子序列
*
* 合并方法:
* 开辟一个辅助空间,将原数组的元素拷贝进去
* 此时辅助空间中的元素分为两个子序列
* 在两个子序列的头部(begin,mid+1处)分别设置一个指针
* 左指针处的元素和右指针处的元素进行比较,较小的元素覆盖进原数组
*
*/
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args) {
int[] array = {2,3,12,8,98,56,33,7,7};
mergeSort(array,0,array.length - 1);
System.out.println(Arrays.toString(array));
}
public static void mergeSort(int[] array, int begin, int end) {
int mid = (begin + end) >> 1;
if(begin < end) {
mergeSort(array, begin,mid);
mergeSort(array,mid + 1,end);
merge(array,begin,mid,end);
}
}
public static void merge(int[] array,int begin,int mid,int end) {
int[] helper = array.clone(); //将数组中的数据拷贝到辅助空间中
int left = begin; //左侧队伍的头部指针
int right = mid +1;//右侧队伍的头部指针
int current = begin; //原数组的指针,指向待填入的位置
while(left <= mid && right <= end) {
if(helper[left] <= helper[right]) {
array[current] = helper[left];
current++;
left++;
}
else {
array[current] = helper[right];
current++;
right++;
}
}
while(left <= mid) { //当右侧队伍走完而左侧还没走完时(左侧走完右侧没走完时无需操作)
array[current] = helper[left];
current++;
left++;
}
}
}