归并排序算法原理及实现
6.8 归并排序
6.8.1归并排序介绍
归并排序(merge sort)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
6.8.2 基本思想
对于一个待排序的数组,首先进行分解,将整个待排序数组以mid中间位置为界,一分为二,随后接着分割,直至到最小单位无法分割;开始进行治的操作,将每两个小部分进行比较排序,并逐步合并;直至合并成整个数组的大小。从而完成了整个排序的过程。
以数据{8,4,5,7,1,3,6,2}为例,归并排序思想的示意图如下:
首先是分的步骤,将整个数组进行分割,分成了若干个单独的较小的单元。
然后是合并的过程,分别将分开的两个较小单元进行比较合并到原来的数组里面;将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],步骤如下图所示:
6.8.3 代码实现
package com.kevin.sortAlgorithm;import java.util.Arrays;/*** @author : kevin ding* @date : 2022/3/10 22:20* @description : 归并排序 采用经典的分治策略,先将问题分解成一些笑的问题,然后递归求解*/
public class MergeSortDemo {public static void main(String[] args) {int[] array = {8,4,5,7,1,3,6,2};int[] tempArray = new int[array.length];System.out.println("merge排序之前:");System.out.println(Arrays.toString(array));mergeSort(array, 0, array.length-1, tempArray);System.out.println("merge排序之后:");System.out.println(Arrays.toString(array));}public static void mergeSort(int[] array, int left, int right, int[] tempArray){// 先开始分,在合并。分之前 必须保证left < right才能分if(left < right){// 分之前 先先求解中间值int mid = (left + right) / 2;// 向左 接着分,以left为左边界,以mid为右边界mergeSort(array, left, mid, tempArray);// 向右接着分 以mid+1为左边界,right为右边界mergeSort(array, mid+1, right, tempArray);// 分完之后,开始合并merge(array, left, mid, right, tempArray);}}/**** @param array 待排序的数组* @param left 待排序数组的左边界* @param mid 待排序数组的中间值 (左右两个有序序列的界限)* @param right 待排序数组的右边界* @param tempArray 临时数组,存放部分排序好的数据*/public static void merge(int[] array, int left, int mid, int right, int[] tempArray){int leftIndex = left; // 左边有序数组的索引int rightIndex = mid+1; // 右边有序数组的索引int tempIndex = 0; // 定义临时数组的索引// 1. 将左右两边有序数组中的数,按照大小依次放入的tempArray中,直到其中一个有序数组放入完毕// 左边有序数组的右边界为mid,右边数组的右边界为right,只要任一索引到边界,则遍历结束while (leftIndex <= mid && rightIndex <= right){if(array[leftIndex] <= array[rightIndex]){// 左边序列的当前值小,将其存入tempArray中,随后将索引分别后移一位tempArray[tempIndex] = array[leftIndex];tempIndex += 1;leftIndex += 1;}else{// 否则,右边序列的当前值较小,存入tempArray中tempArray[tempIndex] = array[rightIndex];tempIndex += 1;rightIndex += 1;}}// 2. 将剩余一个有序数组的值全部依次放入到临时数组tempArray中// 左边有序数组还有剩余while(leftIndex <= mid){tempArray[tempIndex] = array[leftIndex];tempIndex += 1;leftIndex += 1;}// 右边有序数组还有剩余while(rightIndex <= right){tempArray[tempIndex] = array[rightIndex];tempIndex += 1;rightIndex += 1;}// 3.将临时数组中已排好序的值,再拷贝回原数组中// 拷贝回去时,tempIndex每次都是从零开始,因为每次合并的时候都是从零位置开始往里放tempIndex = 0;// 往回拷贝,并非每次都是拷贝所有,是根据传入的参数left和right来定的int tempLeftIndex = left;// 开始拷贝,从left到rightwhile(tempLeftIndex <= right){array[tempLeftIndex] = tempArray[tempIndex];tempLeftIndex += 1;tempIndex += 1;}}
}
归并排序算法原理及实现相关推荐
- 【排序算法】归并排序算法原理
归并排序 概念 使用前提 算法思路 适用场景 算法描述 递归法(Top-down) 分而治之 迭代法(Bottom-up) 迭代 概念 归并排序是建立在归并操作上的一种有效的排序算法. 该算 ...
- 归并排序算法详解(方法一)之C语言版
一.算法原理 归并排序是一种常用的排序算法,属于稳定排序法,其时间复杂度为 归并排序就是将两个已经分别排好序的数组A和B合并为一个排好序的数组C. 如果数组散乱的数组,则需要将数组元素分别按照长度为d ...
- 常见排序算法原理及实现——第二部分(归并排序、快速排序、堆排序)
引言 排序算法第一部分,我们聊了冒泡排序.插入排序.选择排序这三种排序算法,它们的时间复杂度比较高,都是 O(n2),适合小规模数据的排序.今天,我们来看三种时间复杂度为 O(nlogn) 的排序算法 ...
- 算法原理:大数据处理的分治思想!
↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:周彬莲,东北石油大学,Datawhale优秀学习者 引言 MapR ...
- C++ 十大经典排序算法原理及模板之STL方法实现以及稳定性分析
写在前面: 1.本文中默认排序为升序,降序的原理类似. 2.如果程序直接复制到vs出现无法识别标记的问题,解决方法在这:vs无法识别标记的解决方法 3.本文的算法都是自己用stl实现的,疏漏之处还请指 ...
- PHP 实现归并排序算法
算法原理 下列动图来自@五分钟学算法,演示了归并算法的原理和步骤. 原理: 利用递归,先拆分.后合并.再排序. 步骤: 均分数列为两个子数列 递归重复上一步骤,直到子数列只有一个元素 父数列合并两个子 ...
- 排序算法:归并排序算法实现及分析
归并排序算法介绍 归并排序(Merging Sort)就是利用归并的思想实现排序的放.它的原理是假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个 ...
- 有序序列的二分查找、冒泡排序、归并排序算法实战解析
本节开始讲解一下几个简单的算法,原理都在那本书上,大家自己看吧,我就不做搬运工了,这里不同的是,我把vector接口函数单独拿出来进行测试了,深深的体会到算法的奥妙之处,等你深入理解了你会情不自禁拍案 ...
- 排序算法系列:归并排序算法
概述 上一篇我们说了一个非常简单的排序算法--选择排序.其复杂程序完全是冒泡级的,甚至比冒泡还要简单.今天要说的是一个相对比较复杂的排序算法--归并排序.复杂的原因不仅在于归并排序分成了两个部分进行解 ...
最新文章
- LLDB命令查看内存的分配历史
- WPF 之 调用线程必须为 STA,因为许多 UI 组件都需要
- 穷不过三代,囧不过三个公司——程序员如何通过努力让自己看上去很光鲜
- 求圆和椭圆上任意角度的点的坐标
- 深入.net平台的分层开发
- 【转】C#打包文件夹成zip格式(包括文件夹和子文件夹下的所有文件)
- Powerbi实战--常用新建表代码(单位切换,日期表)
- 互动直播的视频录制与合成—支持多人离线重入
- RTX5 | 消息队列03 - 获取消息队列里消息的数量,并一次性提取出来
- 使用Visual Studio Code进行由内而外的C#开发
- 小程序积分商城如何实现营销目的
- AD使用技巧 内附AD18下载地址
- C语言二叉树非递归遍历详解,C语言实现二叉树的递归遍历和非递归遍历
- 纪检委,检察院的工资
- delphi java aes_Delphi AES加密(转)
- 长安清酒·花酿清酒一瓣心醉的甜香
- Spring的配置项aspectj-autoproxy
- 递归实现数组的扁平化
- 网站运营中活动组织的三项注意
- slider wpf 垂直_继续聊WPF——Slider控件
热门文章
- Postgres分表
- python文件只读打开模式是,在Python中将文件更改为只读模式
- Python3.xprint时只回车不换行方法
- 《炬丰科技-半导体工艺》不同电解质对多孔氮化镓的影响
- 【Java】电子凭证-Java生成PDF
- Android Studio连接手机详细教程(包含遇到的问题集)
- Python——类与对象(为啥要用类和对象?有什么好处?)
- python小工具脚本_python实现倒计时小工具
- 50天50个前端小项目(纯html+css+js)第八天(形成波浪动画结合登录表单)
- 卸载ie法,终于把2345.com 清除了。