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;}}
}

归并排序算法原理及实现相关推荐

  1. 【排序算法】归并排序算法原理

    归并排序 概念 使用前提 算法思路 适用场景 算法描述 递归法(Top-down) 分而治之 迭代法(Bottom-up) 迭代 概念   归并排序是建立在归并操作上的一种有效的排序算法.    该算 ...

  2. 归并排序算法详解(方法一)之C语言版

    一.算法原理 归并排序是一种常用的排序算法,属于稳定排序法,其时间复杂度为 归并排序就是将两个已经分别排好序的数组A和B合并为一个排好序的数组C. 如果数组散乱的数组,则需要将数组元素分别按照长度为d ...

  3. 常见排序算法原理及实现——第二部分(归并排序、快速排序、堆排序)

    引言 排序算法第一部分,我们聊了冒泡排序.插入排序.选择排序这三种排序算法,它们的时间复杂度比较高,都是 O(n2),适合小规模数据的排序.今天,我们来看三种时间复杂度为 O(nlogn) 的排序算法 ...

  4. 算法原理:大数据处理的分治思想!

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:周彬莲,东北石油大学,Datawhale优秀学习者 引言 MapR ...

  5. C++ 十大经典排序算法原理及模板之STL方法实现以及稳定性分析

    写在前面: 1.本文中默认排序为升序,降序的原理类似. 2.如果程序直接复制到vs出现无法识别标记的问题,解决方法在这:vs无法识别标记的解决方法 3.本文的算法都是自己用stl实现的,疏漏之处还请指 ...

  6. PHP 实现归并排序算法

    算法原理 下列动图来自@五分钟学算法,演示了归并算法的原理和步骤. 原理: 利用递归,先拆分.后合并.再排序. 步骤: 均分数列为两个子数列 递归重复上一步骤,直到子数列只有一个元素 父数列合并两个子 ...

  7. 排序算法:归并排序算法实现及分析

    归并排序算法介绍 归并排序(Merging Sort)就是利用归并的思想实现排序的放.它的原理是假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个 ...

  8. 有序序列的二分查找、冒泡排序、归并排序算法实战解析

    本节开始讲解一下几个简单的算法,原理都在那本书上,大家自己看吧,我就不做搬运工了,这里不同的是,我把vector接口函数单独拿出来进行测试了,深深的体会到算法的奥妙之处,等你深入理解了你会情不自禁拍案 ...

  9. 排序算法系列:归并排序算法

    概述 上一篇我们说了一个非常简单的排序算法--选择排序.其复杂程序完全是冒泡级的,甚至比冒泡还要简单.今天要说的是一个相对比较复杂的排序算法--归并排序.复杂的原因不仅在于归并排序分成了两个部分进行解 ...

最新文章

  1. LLDB命令查看内存的分配历史
  2. WPF 之 调用线程必须为 STA,因为许多 UI 组件都需要
  3. 穷不过三代,囧不过三个公司——程序员如何通过努力让自己看上去很光鲜
  4. 求圆和椭圆上任意角度的点的坐标
  5. 深入.net平台的分层开发
  6. 【转】C#打包文件夹成zip格式(包括文件夹和子文件夹下的所有文件)
  7. Powerbi实战--常用新建表代码(单位切换,日期表)
  8. 互动直播的视频录制与合成—支持多人离线重入
  9. RTX5 | 消息队列03 - 获取消息队列里消息的数量,并一次性提取出来
  10. 使用Visual Studio Code进行由内而外的C#开发
  11. 小程序积分商城如何实现营销目的
  12. AD使用技巧 内附AD18下载地址
  13. C语言二叉树非递归遍历详解,C语言实现二叉树的递归遍历和非递归遍历
  14. 纪检委,检察院的工资
  15. delphi java aes_Delphi AES加密(转)
  16. 长安清酒·花酿清酒一瓣心醉的甜香
  17. Spring的配置项aspectj-autoproxy
  18. 递归实现数组的扁平化
  19. 网站运营中活动组织的三项注意
  20. slider wpf 垂直_继续聊WPF——Slider控件

热门文章

  1. Postgres分表
  2. python文件只读打开模式是,在Python中将文件更改为只读模式
  3. Python3.xprint时只回车不换行方法
  4. 《炬丰科技-半导体工艺》不同电解质对多孔氮化镓的影响
  5. 【Java】电子凭证-Java生成PDF
  6. Android Studio连接手机详细教程(包含遇到的问题集)
  7. Python——类与对象(为啥要用类和对象?有什么好处?)
  8. python小工具脚本_python实现倒计时小工具
  9. 50天50个前端小项目(纯html+css+js)第八天(形成波浪动画结合登录表单)
  10. 卸载ie法,终于把2345.com 清除了。