文章目录

  • 一、归并排序介绍
  • 二、图解
  • 三、代码分析
    • 1.合并有序数组
    • 2.分的过程
  • 三、完整代码

一、归并排序介绍

归并排序使用的方法是分治法,即将问题分解为许多类似的小问题然后递归求解。

这里不做详细分析,直接看图解过程。

二、图解


分的过程:可以直接除以二分割(这里总数是奇数也可以)。
治的过程:核心是合并两个有序的数组。

三、代码分析

1.合并有序数组

归并排序的核心就是治的过程也就是合并两个有序的数组。实现过程如下(以升序排序为例):

  1. 两指针分别指向数组的头部,并构建一个长度是两个数组之和的临时数组,用于存储数据。
  2. 两指针所在位置的值比较,将值小的填入临时数组中,其所在的指针后移一位。
  3. 反复进行2步骤,直到有一个数组的指针越界,将另外一个数组的所有后续元素依次填入临时数组中,合并完成。

图解
以arr1 = {1,5,6};arr2 ={3,7,9}为例。

左右比较,填入1,左边后移一位。

左右比较,填入3,右边后移一位。

左右比较,填入5,左边后移一位。

左右比较,填入6,左边后移一位。

指针越界,将右边元素依次填入。

合并完成。

代码
下面代码中合并的是原始数组中arr[left 到 mid]段与arr[mid+1 到 right]段,故最后将临时数组temp中的元素拷贝会arr[left 到 right]段(因为整个排序过程是还在原始数组中进行的)。left,mid,right这是进行假想的分割,详细的分的过程后面的代码。

/*** 【合并】两个有序数组* @param arr 总数组* @param left 左数组开始指针(arr左指针)* @param mid  右数组开始指针* @param right  右指针(arr右指针)*/
public static void merge(int[] arr, int left, int mid, int right){int[] temp = new int[right-left+1];int l = left;//左数组初始索引int m = mid + 1;//右数组初始索引int t = 0;//临时数组初始索引//1.将左右数组元素按规则填入temp数组中while(l <= mid && m <= right){if(arr[l] > arr[m]){temp[t] = arr[m];m++;t++;}else{temp[t] = arr[l];l++;t++;}}//2.将数组剩余元素填入temp中if(l > mid){while(m <= right){temp[t] = arr[m];m++;t++;}}else{while(l <= mid ){temp[t] = arr[l];l++;t++;}}//3.将temp数组拷贝到arr中t = 0;l = left;while(l <= right){arr[l] = temp[t];l++;t++;}}

2.分的过程

代码
使用递归进行分割,然后使用merge方法合并数组。

public static void Sort(int[] arr, int left, int right){if(left < right){int mid = (left+right)/2;//取中间值Sort(arr, left, mid);//分Sort(arr, mid+1, right);//分merge(arr, left, mid, right); //治}}

三、完整代码

public static void main(String[] args) {int arr[] = {4,5,8,20,6,87,12,65,0,855,12,5,78};mergeSort(arr);System.out.println(Arrays.toString(arr));}public static void mergeSort(int[] arr){Sort(arr, 0, arr.length() - 1);}public static void Sort(int[] arr, int left, int right){if(left < right){int mid = (left+right)/2;//取中间值Sort(arr, left, mid);//分Sort(arr, mid+1, right);//分merge(arr, left, mid, right); //治}}public static void merge(int[] arr, int left, int mid, int right){int[] temp = new int[right-left+1];int l = left;//左数组初始索引int m = mid + 1;//右数组初始索引int t = 0;//临时数组初始索引//1.将左右数组元素按规则填入temp数组中while(l <= mid && m <= right){if(arr[l] > arr[m]){temp[t] = arr[m];m++;t++;}else{temp[t] = arr[l];l++;t++;}}//2.将数组剩余元素填入temp中if(l > mid){while(m <= right){temp[t] = arr[m];m++;t++;}}else{while(l <= mid ){temp[t] = arr[l];l++;t++;}}//3.将temp数组拷贝到arr中t = 0;l = left;while(l <= right){arr[l] = temp[t];l++;t++;}}
}

测试结果:
[0, 4, 5, 5, 6, 8, 12, 12, 20, 65, 78, 87, 855]

归并排序算法图解分析相关推荐

  1. 【java排序】 归并排序算法、堆排序算法

    一.归并排序算法 基本思想: 归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并 ...

  2. JavaScript实现MergeSort归并排序算法(附完整源码)

    JavaScript实现MergeSort归并排序算法(附完整源码) Comparator.js完整源代码 Sort.js完整源代码 MergeSort.js完整源代码 Comparator.js完整 ...

  3. C语言merge sort归并排序算法(附完整源码)

    C语言merge sort归并排序算法 merge sort归并排序算法的完整源码(定义,实现) merge sort归并排序算法的完整源码(定义,实现) #ifndef MERGE_SORT_H # ...

  4. python 归并排序算法_python基本算法之实现归并排序(Merge sort)

    0.前言 评判一个算法的好坏的标准: 时间复杂度 空间复杂度 1.归并排序算法是什么? 冒泡排序(Bubble Sort)是一种建立在归并操作上面的一种有效的排序算法,由John von neuman ...

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

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

  6. 算法竞赛——归并排序算法

    算法竞赛--归并排序算法 分治法 划分问题:把序列分成元素个数尽量相等的两半 递归求解:把两半元素分别排序 合并问题:把两个有序表合并成一个 借鉴RuJia的精妙的合并过程 void merges2( ...

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

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

  8. 第十五周 项目三 归并排序算法的改进

    /* * Copyright (c)2017,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名称:项目3.cpp * 作 者:孙仁圆 * 完成日期:2017年12 ...

  9. C++ 不知算法系列之聊聊希尔、归并排序算法中的分治哲学

    1. 前言 排序算法中,冒泡.插入.选择属于相类似的排序算法,这类算法的共同点:通过不停地比较,再使用交换逻辑重新确定数据的位置. 希尔.归并.快速排序算法也可归为同一类,它们的共同点都是建立在分治思 ...

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

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

最新文章

  1. golang http 操作 简介
  2. msvc MinGW gcc g++关系
  3. unresolved external symbol怎么解决_收藏!用Kubernetes和PKS 1.5解决Windows Server2008的问题...
  4. [云炬创业基础笔记]第五章创业机会评估测试11
  5. 双项通过|百度点石通过信通院「可信数据流通平台」、「联邦学习」双项测评
  6. 物联网正占据有利风口 2017年实现商用不难
  7. python 计量经济 35岁 工作_Python在计量经济与统计学中的应用
  8. 全排列及相关扩展算法(四)——原始中介数通过逆推求原排列算法
  9. 计算机电源故障维修方法,常见电源故障维修技巧
  10. C#:异步编程和线程的使用(.NET 4.5 )
  11. Qt公有槽和私有槽的区别
  12. 如何将不清晰的扫描版pdf转为清晰的pdf或word
  13. 路由器下一跳地址怎么判断_三分钟了解路由器路由表
  14. 屏蔽所有统计代码(51.la cnzz 百度统计 谷歌分析师adsense、屏蔽淘宝客广告代码)的方法
  15. C++和java的区别和联系
  16. Android各种时间格式转换
  17. HDMI2.1定义以及物理转换Bypass芯片详解
  18. mysql my.cof 配置表空间_my.conf配置大全
  19. 华为云APIG限流控制
  20. 几个比较好的Web前端开发框架

热门文章

  1. 七种方法完美解救你爆满的C盘(瘦身+扩容)
  2. WeUi使用手册及参考
  3. java学生管理系统登录注册_《Java》— 学生管理系统——登录界面
  4. 计算机图形学期刊影响因子,计算机图形学 | CCF推荐期刊专刊信息2条
  5. 黑马程序员ssm总结[大全版本,有对应pdf+源码](spring->springmvc-->springboot-->maven高级->cloud微服务)
  6. 华为交换机双上行组网Smart-link配置指南
  7. android textwatcher 获取当前控件,TextWatcher如何找到调用它的EditText
  8. 惠普台式电脑引导不了系统_惠普电脑进入bios设置引导模式操作步骤图文
  9. 用Android自带的signapk.jar + .x509.pem + .pk8签名应用程序 - anfflee
  10. 博客样式-bbsmax4风格V0.2