归并排序就这么简单

快速排序、堆排序、归并排序简单比较 快速排序、堆排序和归并排序都是平均时间复杂度为O(nlog(n))的算法。有关其原理介绍已经有很多。今天写了个简单的实现,用JFreeChart做了个简单的性能比较。懒得保存在本地,上传一下,以供日后回看。 import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFrame; import org.jfree.ch 阅读详情

归并排序就这么简单

从前面已经讲解了冒泡排序、选择排序、插入排序,快速排序了,本章主要讲解的是归并排序,希望大家看完能够理解并手写出归并排序快速排序的代码,然后就通过面试了!如果我写得有错误的地方也请大家在评论下指出。

归并排序的介绍

来源百度百科:

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

过程描述:

归并过程为:比较a[i]和b[j]的大小,若a[i]≤b[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素b[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

原理:

归并操作的工作原理如下:

第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置

第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

重复步骤3直到某一指针超出序列尾

将另一序列剩下的所有元素直接复制到合并序列尾

下面我就来做个小小的总结:

  • 将两个已排好序的数组合并成一个有序的数组,称之为归并排序
  • 步骤:遍历两个数组,比较它们的值。谁比较小,谁先放入大数组中,直到数组遍历完成

一、演算归并排序过程

现在我有两个已经排好顺序的数组:int[] arr1 = {2, 7, 8}和int[] arr2 = {1, 4, 9},我还有一个大数组来装载它们int[] arr = new int[6];

1.1

那么,我将两个数组的值进行比较,谁的值比较小,谁就放入大数组中!

首先,拿出arr1[0]和arr2[0]进行比较,显然是arr2[0]比较小,因此将arr2[0]放入大数组中,同时arr2指针往后一格

所以,现在目前为止arr = {1}

1.2

随后,拿arr1[0]和arr2[1]进行比较,显然是arr1[0]比较小,将arr1[0]放入大数组中,同时arr1指针往后一格

所以,现在目前为止arr = {1,2}

1.3

随后,拿arr1[1]和arr2[1]进行比较,显然是arr2[1]比较小,将arr2[1]放入大数组中,同时arr2指针往后一格

所以,现在目前为止arr = {1,2,4}

……..

遍历到最后,我们会将两个已排好序的数组变成一个已排好序的数组arr = {1,2,4,7,8,9}

二、归并排序前提分析(分治法)

从上面的演算我们就直到,归并排序的前提是需要两个已经排好顺序的数组,那往往不会有两个已经排好顺序的数组给我们的呀(一般是杂乱无章的一个数组),那这个算法是不是很鸡肋的呢??

其实并不是的,首先假设题目给出的数组是这样子的:int[] arr = {2, 7, 8, 1, 4, 9};

当我们要做归并的时候就以arr[3]也就元素为1的那个地方分开。是然后用一个指针L指向arr[0],一个指针M指向arr[3],用一个指针R指向arr[5](数组最后一位)。有了指针的帮助,我们就可以将这个数组切割成是两个有序的数组了(操作的方式就可以和上面一样了)

可是上面说了,一般给出的是杂乱无章的一个数组,现在还是达不到要求。比如给出的是这样一个数组:int[] arrays = {9, 2, 5, 1, 3, 2, 9, 5, 2, 1, 8};

此时,我们就得用到分治的思想了:

  • 那么我们也可以这样想将int[] arr = {2, 7, 8, 1, 4, 9};数组分隔成一份一份的,arr[0]它是一个有序的”数组”,arr[1]它也是一个有序的”数组”,利用指针(L,M,R)又可以像操作两个数组一样进行排序。最终合成{2,7}…….再不断拆分合并,最后又回到了我们的arr = {1,2,4,7,8,9},因此归并排序是可以排序杂乱无章的数组的

这就是我们的分治法—>将一个大问题分成很多个小问题进行解决,最后重新组合起来

三、归并代码实现

实现步骤:

  1. 拆分
  2. 合并

……..



    public static void main(String[] args) {
        int[] arrays = {9, 2, 5, 1, 3, 2, 9, 5, 2, 1, 8};
        mergeSort(arrays, 0, arrays.length - 1);

        System.out.println("公众号:Java3y" + arrays);


    }

    /**
     * 归并排序
     *
     * @param arrays
     * @param L      指向数组第一个元素
     * @param R      指向数组最后一个元素
     */
    public static void mergeSort(int[] arrays, int L, int R) {

        //如果只有一个元素,那就不用排序了
        if (L == R) {
            return;
        } else {

            //取中间的数,进行拆分
            int M = (L + R) / 2;

            //左边的数不断进行拆分
            mergeSort(arrays, L, M);

            //右边的数不断进行拆分
            mergeSort(arrays, M + 1, R);

            //合并
            merge(arrays, L, M + 1, R);

        }
    }


    /**
     * 合并数组
     *
     * @param arrays
     * @param L      指向数组第一个元素
     * @param M      指向数组分隔的元素
     * @param R      指向数组最后的元素
     */
    public static void merge(int[] arrays, int L, int M, int R) {

        //左边的数组的大小
        int[] leftArray = new int[M - L];

        //右边的数组大小
        int[] rightArray = new int[R - M + 1];

        //往这两个数组填充数据
        for (int i = L; i < M; i++) {
            leftArray[i - L] = arrays[i];
        }
        for (int i = M; i <= R; i++) {
            rightArray[i - M] = arrays[i];
        }


        int i = 0, j = 0;
        // arrays数组的第一个元素
        int  k = L;


        //比较这两个数组的值,哪个小,就往数组上放
        while (i < leftArray.length && j < rightArray.length) {

            //谁比较小,谁将元素放入大数组中,移动指针,继续比较下一个
            if (leftArray[i] < rightArray[j]) {
                arrays[k] = leftArray[i];

                i++;
                k++;
            } else {
                arrays[k] = rightArray[j];
                j++;
                k++;
            }
        }

        //如果左边的数组还没比较完,右边的数都已经完了,那么将左边的数抄到大数组中(剩下的都是大数字)
        while (i < leftArray.length) {
            arrays[k] = leftArray[i];

            i++;
            k++;
        }
        //如果右边的数组还没比较完,左边的数都已经完了,那么将右边的数抄到大数组中(剩下的都是大数字)
        while (j < rightArray.length) {
            arrays[k] = rightArray[j];

            k++;
            j++;
        }
    }

我debug了一下第一次的时候,就可以更容易理解了:

  • 将大数组的前两个进行拆分,然后用数组装载起来

  • 比较小数组的元素哪个小,哪个小就先放入大数组中

上面的两个步骤不断循环,最后得出有序的数组:

四、归并排序的优化

来源:http://www.cnblogs.com/noKing/p/7940531.html

我这里整理一下要点,有兴趣的同学可到上面的链接上阅读:

  • 当递归到规模足够小时,利用插入排序
  • 归并前判断一下是否还有必要归并
  • 只在排序前开辟一次空间

如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y

c++之超简单的归并排序 归并排序: 基于递归思想,是一种递归树法。 ==将目标数组拆分成两半,对每半在进行拆分,如此不断进行下去,直到数组的左边界大于右边界,形成交叉才结束。每一次拆分都要进行合并,把拆分的两个数组合并成一个。 代码如下: #include<bits/stdc++.h> using namespace std; #define N 1000 int a[N],b[N]; int n; using namespace std; void Merge(int left,int mid,int rig. 阅读详情

相关推荐

提升仿真效率:Synopsys VCS高级编译选项优化技巧(2023最新版)

本文深入探讨了Synopsys VCS 2023版本中的高级编译选项优化技巧,帮助工程师提升仿真效率。通过并行编译、智能代码分析、精准覆盖率采样等策略,结合真实案例展示如何显著缩短仿真周期并优化资源使用,适用于数字芯片验证和大型SoC设计。

weixin_30338481的博客 114

排序算法-归并排序

文章目录基本思想递归方法的实现 基本思想 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 将已经有序的子序列合并,得到完全有序的序列; 即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 下面是一次归并排序的流程图 递归方法的实现 通过对排序流程的了解,我们发现其实排序的过程大致可以分为两个部分。 首先需要对被排数据进行分割,直到把每组分割的只剩一个数据。

qq_45967533的博客 1666

川崎机器人总线通信_三菱PLC和发那科机器人进行CCLINK总线通信

三菱CCLINK主站模块采用QJ61BT11N,该模块用在Q系列PLC上,如果是5U或3UPLC,可用FX5-CNV-BUS加FX3U-16CCL-M或FX5-CCL-M模块。本教程以Q系列为例CCLINK接线方法如下模块拨码含义如下接线和拨码设置好后,接着在编程软件上设置CCLINK通信参数打开编程软件,在工程导航栏打开参数——网络参数,选中CCLINK打开。打开如下画面起始IO为模块本体占用I...

weixin_42300398的博客 7548

归并排序

归并排序 public class MergeSort { public static void main(String[] args) { int i = 0; int a[] = { 5, 4, 9, 7, 8, 0, 6, 1, 3, 2 }; int len = a.length; MergeSort(a, 0, len - 1); for (Integer x

Shangri-La 1005

快速了解Spyder

一 面板介绍菜单栏:放置所有功能工具栏:放置快捷菜单,可以通过菜单栏中的View的Toolbars的复选框来勾选工作区:写代码的地方属性页的标题栏:可以显示当前代码的名字和位置查看栏:查看文件、调试时的对象及变量输出栏:查看程序的输出信息,也可以作为shell终端来输入Python语句状态栏:用来显示当前文件权限、编码,光标指向位置和系统内存二 注释功能注释功能为编写代码很常用功能,下面介绍Spy...

实践求真知 1万+

智能温室:温室环境监测_(7).土壤监测技术包括pH值和电导率

土壤的pH值是指土壤溶液的酸碱度,它对植物的营养吸收和生长发育有着重要的影响。在智能温室中,土壤监测是非常重要的一个环节,因为土壤的pH值和电导率直接影响植物的生长和健康。本节将详细介绍如何利用传感器和数据处理技术来监测土壤的pH值和电导率,并提供具体的代码示例。在智能温室中,监测到的土壤pH值和电导率数据需要传输到中央控制系统进行进一步的处理和分析。通过以上步骤,您可以构建一个完整的智能温室土壤监测系统,实时监控土壤的pH值和电导率,确保植物在最佳的生长环境中。校准通常包括在已知电导率的标准溶液中进行。

zhubeibei168的博客 1408

排序【4.1】归并排序(MergeSort)

归并排序(Merge Sort) 1、基本思想: 将两个的有序数列合并成一个有序数列,我们称之为&quot;归并&quot;。 归并排序(Merge Sort)就是利用归并思想对数列进行排序。根据具体的实现,归并排序包括&quot;从上往下&quot;和&quot;从下往上&quot;2种方式。 (1)从下往上的归并排序:将待排序的数列分成若干个长度为1的子数列,然后将这些数列两两合并;得到若干个长度为2的有序数列,再将这些数列两两合并;得到若干个长度为4..

简之的通向技术之路 1032

GRCNN抓取网络学习2【自制Jacquard数据集训练】

请先完成【机械臂视觉抓取从理论到实战】,这样有利于下面操作的理解!然后第二步是GRCNN抓取网络1【Jacquard数据集等效抓取集制作】,有了自己的数据集输入到GRCNN中是三种文件,接下来就是准备训练GRCNN网络啦!grasps.txtRGB.png本文帮大家根据自制Jacquard数据集训练GRCNN抓取网络,其中包含数据格式的对齐,列举了常见的几种训练方法,相信能坚持到这里的都应该试试顺利了吧!接下来会针对GRCNN调优,期待一下下吧,那就别宁色你的三连。

vor234的博客 2797

归并排序【超详细+代码】(递归+非递归)

将已有序的子序合并,从而得到完全有序的序列,即先使每个子序有序,再使子序列段间有序。Onlogn。

qq_65518575的博客 1544

8.26华为OD机试真题 新系统 - 仓库查询 (Java/Py/C/C++/Js/Go)

8.26华为OD机试真题 新系统 - 仓库查询 (Java/Py/C/C++/Js/Go)

算法大师! 1737

get_ccopt系列命令介绍

get_ccopt_property:用来获取cts阶段,clock tree上所有的参数信息,可以通过get_ccopt_property –help *获取所有参数。get_ccopt_skew_group_delay:用来获取skew group的相关信息,可以通过筛选出特定条件下skew_group的参数,如skew_group下latency最长是多少;get_ccopt_clock_tree_source_groups:获取clock tree的source group名字;

芯冰乐 281

C++复习之简单选择排序&归并排序

简单选择排序 (simple selection sort) 就是通过 n-i 次关键字之间的比较 , 从 n-i+1个记录中选择关键字最小的记录 , 并和第 i(1<=i<=n) 个记录交换之尽管与冒泡排序同为 O(n^2), 但简单选择排序的性能要略优于冒泡排序void selectSort(int *arr, int n) { for (int i = 0; i < n; i++)

MasonChen的专栏 423

嵌入式软件工程师面试题目整理(一)

文章目录嵌入式软件工程师面试题目整理(一)Arm有多少32位寄存器?Arm2440和6410有什么区别CPU,MPU,MCU,SOC,SOPC联系与差别上拉&下拉&高阻态串口协议讲一讲RS232和RS485通讯接口有什么区别IIC时序图画一下,IIC有哪些状态,给一个字节,将它发送出去。IIC有什么注意事项?有没有用I/O模拟IIC,如果有需要注意什么?为什么2440的内存起始地址是3后面7个0呢?为什么6410的内存起始地址是5后面7个0呢?内存管理有什么看法?(MMU)锁有哪些?有什么注

嵌入式与Linux那些事的博客 7883

poj2388 简单排序——归并排序

这个题是一个很水的排序题,C/C++本身就提供了排序函数而且速度已经很好(n*log(n))的复杂度。只是前两天数据库老师讲课的时候提到了归并排序,自己就觉得当时学的时候有点模糊,今晚就自己敲了一下,发现也没当初想的那么难。 其实,归并排序有好多应用场景,比喻求逆序对数就是其经典的用法。 算法思想很简单,就不多说了,直接贴代码吧。 poj2388 #include #include #de

ZT在努力 466

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C++简单的归并排序

归并排序 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 ·····················································...

千苏的博客 620

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

简单选择排序、直接插入排序、归并排序

一、简单选择排序基本思想: 在要排序的一组数中,选出最小的一个数与第一个位置的数交换; 然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。 实例: Java实现:package com.tao.algorithm;/** * Created by michael on 17-8-13. */ public class 简单选择排序 {

西瓜游侠的博客 708

最简单易懂的归并排序

(一) 归并排序 归并排序(Merge Sort):归并排序的核心思想还是蛮简单的。如果要排序一个数组,我们先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了。 归并排序使用的就是分治思想,分治,顾名思义,就是分而治之,将一个大问题分解成小的子问题来来解决。小的子问题解决了,大问题也就解决了。 分治算法一般都是用递归来实现的。分治是一种解...

小丽 637

归并排序的简单理解

归并排序的基本思想是,将已有序的子序列合并,可以得到有序的完整序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为。每次合并操作的平均时间复杂度为 O(n),而完全二叉树的深度为 log2⁡n,总的平均时间复杂度为 O(nlog⁡n)。归并排序速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的序列。归并排序的比较次数小于快速排序的比较次数,移动次数一般多于快速排序的移动次数。并且,归并排序的最好、最坏、平均时间复杂度均为 O(nlog⁡n)。

csdn_manong1的博客 229

排序笔记(2)选择排序(简单选择排序+堆排序)、归并排序

文章目录排序分类(3)选择排序1.简单选择排序理论:代码:2.堆排序理论:代码:(4)归并排序理论:代码:(5)分配排序理论:代码: 排序分类 (3)选择排序 1.简单选择排序 首先通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换。 再通过n-2次比较,从剩余的n-1个记录中找出关键字次小的记录,将它与第二个记录交换。 重复上述操作,共进行n-1趟排序后,排序结束。 理论: 例:将数组[1 5 3 2]按照从小到大的顺序排序。 注:【】内为已经排好序的数 第一轮 : min

qq_46126258的博客 1041

python 中的冒泡、简单选择、快速排序、归并排序 实现

#简单排序 def simpleSort(lis): for i in range(len(lis)): for j in range(i,len(lis)): if lis[i] > lis[j]: lis[i],lis[j] = lis[j],lis[i] return lis #快速排序 de...

yournevermore的博客 176

数据结构-简单选择排序和归并排序

本文内容 通用数据结构 简单选择排序 归并排序 Main 函数 运行结果   本文用 CodeBlocks 编写。同时也提供 VS C 和 VS C# 代码。   通用数据结构 MyElement.h #ifndef MYELEMENT_H_INCLUDED #define MYELEMENT_H_...

weixin_34315189的博客 179

简单的归并排序算法

归并排序

冻冰粉星的博客 577

归并排序原来可以这么简单

归并排序 题目描述 给定你一个长度为n的整数数列。 请你使用归并排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。 输入格式 输入共两行,第一行包含整数 n。 第二行包含 n 个整数(所有整数均在111 ~$ 10^9$范围内),表示整个数列。 输出格式 输出共一行,包含 n 个整数,表示排好序的数列。 数据范围 1≤n≤1000001≤n≤1000001≤n≤1000001≤n≤...

Hemx的博客 522
上一篇: Elasticsearch就这么简单
下一篇: 堆排序就这么简单
Java3y
Java3y 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 1万+粉丝 509原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值