归并排序
来源:互联网 发布:疯狂原始人 知乎 编辑:程序博客网 时间:2024/06/05 22:56
归并排序
基本思想
归并排序其实是分治思想的体现,先解决小规模的问题,小规模的问题解决后,大的问题自然就会得到解决。
例如对于长度为15的数组a,先将子数组a[0-7]排序,再将a[8-14]排序,这两个子数组排序后归并结果即可。整个过程其实可以用一个二叉树来表示:
图1 归并排序示意图
归并两个已经排序的子数组的过程中,需要将这两个子数组的值复制到另一个临时数组中,再从小到大归并到原数组。
代码实现
代码实现如下:
/** * <p>文件描述: 归并排序</p> * * @Author luanmousheng * @Date 17/8/1 下午2:46*/public class MergeSort { //归并时用到的临时空间 private static int[] temp; public static void sort(int[] arr) { if (arr == null) { return; } sort(arr, 0, arr.length - 1); } private static void sort(int[] arr, int lo, int hi) { //如果数组开始位置大于等于结束位置,说明本次排序完成,返回 if (lo >= hi) { return; } //取中间位置 int mid = (lo + hi) /2; //将左边的部分排序 sort(arr, lo, mid); //将右边的部分排序 sort(arr, mid+1, hi); //此时两边已经是排序的,归并结果 merge(arr, lo, mid, hi); } private static void merge(int[] arr, int lo, int mid, int hi) { //先将原数组lo到hi处的值复制到临时数组 for (int i = lo; i <= hi; i++) { temp[i] = arr[i]; } //i是左边数组的开始位置 int i = lo; //j是右边数组的开始位置 int j = mid+1; //遍历原数组lo到hi位置, for (int k = lo; k <= hi; k++) { if (i > mid) { //左边部分已经遍历完 arr[k] = temp[j++]; } else if (j > hi) { //右边部分已经遍历完 arr[k] = temp[i++]; } else if (temp[i] < temp[j]) { //取较小的值放到原来数组的位置k处 arr[k] = temp[i++]; } else { arr[k] = temp[j++]; } } } public static void main(String[] args) { int[] arr = {4,3,5,8,11,9,2,7}; temp = new int[arr.length]; sort(arr); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + ", "); } }}
这里的逻辑就是先递归排序左边的数组,然后递归排序右边的数组,接着归并这两个已经排序完成的数组。
图2 两个有序数组的归并
图2 归并时会将原数组的数据复制到临时数组,临时数组上放上两个指针i和j,分别指向左边数组和右边数组的开始位置,比较这两个位置的值并将较小的值存储到原数组,直到这两个子数组遍历完成。
复杂度
归并排序的空间复杂度为O(n),时间复杂度为O(nlogn)。
阅读全文
0 0
- 归并排序-归并排序
- 归并和归并排序
- 归并与归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 排序::归并
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 百度前端学院task16总结
- Mac 通过 SSH 远程连接Linux服务器
- protobuf应用与原理详解
- python 面向对象高级编程
- 数据结构 二叉树的性质
- 归并排序
- 第5天
- JS&jQuery初级06
- Ajax学习笔记,原生Ajax,使用XMLHttpRequest读取xml内容
- 集训第五天(2017/8/4):刷搜索题
- 学堂在线-数据结构-PA1-范围查询(Range)-解题报告
- 【鸽巢排序】对数组排序,要求时间复杂为O(n)
- Codeforces-540C 广搜BFS
- python数据分析与展示(一)