排序算法(3)----归并排序
这篇博文分为四个部分:
- 归并排序基本思想
- 基础代码实现与解析
- 代码一次优化
- 代码二次优化(自底向上的归并排序)
* 3) * [归并排序] :小到大排序 * 1.循环的将每一个部分都分为原来的一半,直到最后每一部分只剩下一个元素 * 2.循环的将每两个部分进行合并并且排序,直到最后全部合并 * O(n*log n)
static int[] mergeSort(int[] arr) {return __mergeSort(arr, 0, arr.length - 1); }
private static int[] __mergeSort(int[] arr, int left, int right) {if (left >= right) {return arr; } //得到中点位置的下标middle,注意这里最好不要使用 int middle = (right + left) / 2 ,防止 right + left 数据太大造成溢出 int mid = (right - left) / 2 + left; //1.循环的将每一个部分都分为原来的一半,直到最后每一部分只剩下一个元素 __mergeSort(arr, left, mid); __mergeSort(arr, mid + 1, right); //2.循环的将每两个部分进行合并并且排序,直到最后全部合并 // if 条件判断当这两部分需要排序时(即前一部分的最大值要比后一部分的最小值大时),进行排序,否则直接合并即可 if (arr[mid] > arr[mid + 1]) {__merge(arr, left, mid, right); }return arr; }
private static int[] __mergeSort(int[] arr, int left, int right) {if (left >= right) {return arr; }//得到中点位置的下标middle,注意这里最好不要使用 int middle = (right + left) / 2 ,防止 right + left 数据太大造成溢出 int mid = (right - left) / 2 + left; //1.循环的将每一个部分都分为原来的一半,直到最后每一部分只剩下一个元素 __mergeSort(arr, left, mid); __mergeSort(arr, mid + 1, right); //2.循环的将每两个部分进行合并并且排序,直到最后全部合并 // if 条件判断当这两部分需要排序时(即前一部分的最大值要比后一部分的最小值大时),进行排序,否则直接合并即可 if (arr[mid] > arr[mid + 1]) {__merge(arr, left, mid, right); }return arr; }//将 arr[left....mid] 与 arr[mid + 1....right] 两个部分进行归并 private static int[] __merge(int[] arr, int left, int mid, int right) {int[] temarr = new int[right + 1 - left]; //开辟新的空间,这个空间是用来进行排序 // 将 arr 中所有元素复制一份,到 temarr 中,注意这里 arr 是从下标 left 开始的,而 temarr 是从下标 0 开始的 for (int i = left; i < right + 1; i++) {temarr[i - left] = arr[i]; }int i = left; //作为前一部分将要排序的元素的下标 int j = mid + 1; //作为后一部分将要排序的元素的下标 for (int k = left; k <= right; k++) { //k为arr数组中本轮归并中最小值将要覆盖掉的下标 //防止越界,要保证i始终属于前一部分,j始终属于后一部分 if (i > mid) { //表明前一部分已经遍历结束,只需要把后一部分的值依次填入即可 arr[k] = temarr[j - left]; j++; } else if (j > right) {arr[k] = temarr[i - left]; //同理,后一部分已经遍历完毕,只需依次填入前一部分即可 i++; }//一般情况 : 遍历整个数组,比较 temarr[i - left] 与 temarr[j - left] 的大小,将小的直接覆盖原数组arr,将它排到前面,并且将排完序的下标后移 else if (temarr[i - left] < temarr[j - left]) {arr[k] = temarr[i - left]; i++; } else {arr[k] = temarr[j - left]; j++; }}return temarr; }
private static int[] __mergeSort(int[] arr, int left, int right) { //优化 if (left >= right) { //优化 return arr; //优化 } /*优化开始*/ if (right - left <= 10) {int[] temparr = new int[right - left + 1]; for (int i = left; i <= right; i++) {temparr[i - left] = arr[i]; }//使用插入排序进行底层的排序,优化归并排序不断递归到底的消耗 temparr = InsertionSort.insertionSort_3(temparr); for (int i = left; i <= right; i++) {//把 temparr 再回填回到 arr 中 arr[i] = temparr[i - left]; }return arr; }/*优化结束*/ //得到中点位置的下标middle,注意这里最好不要使用 int middle = (right + left) / 2 ,防止 right + left 数据太大造成溢出 int mid = (right - left) / 2 + left; //1.循环的将每一个部分都分为原来的一半,直到最后每一部分只剩下一个元素 __mergeSort(arr, left, mid); __mergeSort(arr, mid + 1, right); //2.循环的将每两个部分进行合并并且排序,直到最后全部合并 // if 条件判断当这两部分需要排序时(即前一部分的最大值要比后一部分的最小值大时),进行排序,否则直接合并即可 if (arr[mid] > arr[mid + 1]) {__merge(arr, left, mid, right); }return arr; }
static int[] mergeSort(int[] arr) {for (int part = 1; part <= arr.length; part += part) {for (int i = 0; i + part < arr.length; i += 2 * part) {if ((i + 2 * part - 1 > arr.length - 1)) {__merge(arr, i, i + part - 1, arr.length - 1); } else {__merge(arr, i, i + part - 1, i + 2 * part - 1); }}}return arr; }
经过这一步的优化,我们甚至都不需要
__mergeSort(int[] arr, int left, int right)
排序算法(3)----归并排序相关推荐
- 排序算法:归并排序、快速排序
相关博客: 排序算法:冒泡排序.插入排序.选择排序.希尔排序 排序算法:归并排序.快速排序 排序算法:桶排序.计数排序.基数排序 排序算法:堆排序 十大排序算法小结 一.归并排序: 1.工作原理: 归 ...
- 排序算法之--归并排序(好玩的一个算法o。o)快速入门
排序算法之--归并排序(好玩的一个算法o.o) 下面是归并操作的基本思路(注意:是归并操作哦,不是归并排序哦) 归并操作的工作原理如下: 第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存 ...
- NOI提高级:排序算法之归并排序、快速排序
图解排序算法(四)之归并排序 图解排序算法(四)之归并排序 - dreamcatcher-cx - 博客园 小学生图解排序算法:⑥归并排序 小学生图解排序算法:⑥归并排序_纯文笔记-CSDN博客_图解 ...
- 数据结构与算法:十大排序算法之归并排序
数据结构与算法:十大排序算法之归并排序 package TopTenSortingAlgorithms;/*** 归并排序:Java** @author skywang* @date 2014/03/ ...
- [Alg]排序算法之归并排序
[Alg]排序算法之归并排序 作者:屎壳郎 miaosg01@163.com 日期:Aug 2021 版次:初版 简介: 归并排序是一类在任何情况下都能保证Nlg(N)N\lg(N)Nlg(N)的排 ...
- 【排序算法】归并排序(C语言)
[排序算法]-- 归并排序(C语言) 目录 一.归并排序的原理 二.两个有序数组排序和合并 1. 原地排序 2. 创建临时空间 二.递归实现 三.非递归实现 1. 实现思路 2. 数组边界问题 3. ...
- 排序算法中——归并排序和快速排序
冒泡排序.插入排序.选择排序这三种算法的时间复杂度都为 $O(n^2)$,只适合小规模的数据.今天,我们来认识两种时间复杂度为 $O(nlogn)$ 的排序算法--归并排序(Merge Sort)和快 ...
- 【DS】排序算法之归并排序(Merge Sort)
一.算法思想 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法的一个非常典型的应用,指的是将两个已经排序的序列合并成一个序列的操作.其归并思想如下: 1)申请空间,使其大小为两个已经 ...
- c语言归并排序代码详细注释,C语言实现排序算法之归并排序详解
排序算法中的归并排序(Merge Sort)是利用"归并"技术来进行排序.归并是指将若干个已排序的子文件合并成一个有序的文件. 一.实现原理: 1.算法基本思路 设两个有序的子文件 ...
- 排序算法-07归并排序(python实现)
归并排序 概述 以归并操作为基础的排序算法,底层算法设计为分治法. 所谓分治法,就是讲问题分解为多个子问题递归求解,再将子问题答案合并. 算法实现 将待排序序列分解为两个,四个,,,n个子部分. 两两 ...
最新文章
- python输入输出流详解_输入输出流的概念
- ISA CMAK 网络访问隔离区
- 《C与指针》第七章练习
- 前端问题记录1:debounce is not a function
- JAVA不同类型数组重载_方法的重载;数组 (Java Day05)
- 史上最全 yum 入门使用教程和常见错误解决办法
- linux c 网络事件 通知,深入理解Linux网络技术内幕—通知链
- 风变python培训_风变python学习小结
- 18 比较数组找出最大两个数
- C#信息采集系统,常见控件练习
- 黄俊:电商系统的一些心得分享
- MySQL – iBatis – 文件存储
- 情感读本杂志情感读本杂志社情感读本编辑部2022年第23期目录
- 不用任何工具重装Win7系统
- 中长焦投影仪买哪款好,当贝X3高流明热销你值得看
- VC++界面编程之--实现工具栏自定义皮肤
- Redis从入门到入坟系列文章(一): keys 命令
- pmp培训机构哪个比较好,求推荐?
- 计算机组成原理(静态随机存取存取器)
- 带你一文读懂SaaS版多租户商城系统对多品牌企业的应用价值
热门文章
- sqlite 模糊匹配日期_SQLite模糊查找(like) | 学步园
- 使用Visual Studio开发游戏——微软宣布与Unity、Unreal Engine和Cocos展开全新合作
- 掘金外链即将失效?论如何用脚本一次性下载/替换失效的外链图片
- megacli组建raid
- 老男孩教育每日一题-124天:当我们使用ssh-keygen命令的时候,如何一键非交互生产密钥对呢?...
- android在activity中锁屏解锁后重走OnCreate的问题的解决办法
- 如何解决无法显示隐藏文件文件夹
- 然后是几点 c语言,2-2. 然后是几点
- android广告页白屏_Android 启动页面与广告页面的实现-Go语言中文社区
- python数据分析是什么意思_选择python进行数据分析的理由和优势