归并排序:步骤讲解与代码实现

归并排序

  在一些常用的排序中,归并排序在时间开销上来说可以是排序中的最佳实践之一(时间复杂度=n*log n),今天我们就来看看归并是如何实现的。

  归并排序大致可以分为两步:

    1、将数组从中间分开,对两边分别排序。

    2、将两个有序的数组进行合并。

  所以实现归并排序主要也就是解决这两个问题。

  下图是归并排序的大致步骤,红线代表将数组拆开,蓝箭头代表将拆后的数组分别处理,红箭头代表将数组排序后返回

问题1:如何将数组分开,并进行分别排序?

答:使用递归实现

问题2:如何将两个有序的数组进行合并排序?

假设如上图的第二行中,需要合并(2,4,5,8)和(1,3,6,7)两个数组。

1,因为这两个数组都是增序的,只需要比较俩个数组的第一个数,那么比较小的数必然是两数组中最小的数。

  例:比较(2,4,5,8)的2 和(1,3,6,7)的1,那么1必然是两数组中最小的数。

2,将这个数放入一个新的数组。

  例:将1放入数组a[]中,两数组还有(2,4,5,8)的2 和(3,6,7)

3,再次重复第1步。

.....

如此比较直到其中一个数组结束,将另一个数组剩下的值全部放入数组a

那么数组a便是排好序的数组。

代码实现:

public class MergesSort {
    //排序函数,target为要排序的数组,
       // begin和end为要排序的区间的开始和结束坐标
    public void mergeSort(int target[],int begin,int end){
        //当要排序的数组区间只有一个数时直接返回
        if((end-begin)==0){
            return ;
        }
        //当排序的数组区间有两个数时,对这两个数进行比较
        if((end-begin==1)){
            sortS2B(target,begin,end);
            return ;
        }
        //当要排序的数组大于2个时,我们就分割此数组的区间,分别排序;
        int mid=(begin+end)/2;
        mergeSort(target,begin,mid);
        mergeSort(target,mid+1,end);

        //将排序好的俩数组的区间进行合并排序

        //创建一个数组用于存放排好序的数组,大小就是区间大小
        int temp[]=new int[end-begin+1];
        //存放第一个数组的开始坐标
        int p1=begin;
        //存放第二个数组的开始坐标
        int p2=mid+1;
        //存放temp数组最近一次存放的数的坐标,初始为0
        int p3=0;      
        while(p1<=mid&&p2<=end){
            //将小的数存到temp数组
            if(target[p1]<target[p2]){
                temp[p3]=target[p1];
                p3++;
                p1++;
            }else{
                temp[p3]=target[p2];
                p3++;
                p2++;
            }
        }
        //检查是否还有没有插入的
        while(p1<=mid){
            temp[p3]=target[p1];
            p3++;
            p1++;
        }
        while(p2<=end){
            temp[p3]=target[p2];
            p3++;
            p2++;
        }
        //将排好的数组temp与原target的替换
        System.arraycopy(temp, 0, target, begin, temp.length);
    }
    //将数组target的a和b坐标的两个数按small to big从小到大排序
    public void sortS2B(int target[],int begin,int end){
        //如果begin>end,进行交换
        if(target[begin]>target[end]){
            int temp=target[begin];
            target[begin]=target[end];
            target[end]=temp;
        }
        return ;
    }

    public static void main(String[] args) {
        MergesSort ms=new MergesSort();

        int a[]={8,-6,2,-7,9,-23,2,7,4,67,1,8};
        //注意第三个参数是数组的结束坐标,应该因为数组是从0开始的,所以结束的坐标需要数组的长度-1
        ms.mergeSort(a,0,a.length-1);
        int i=0;
        while(i<a.length){
            System.out.print(a[i++]+"  ");
        }
    }

}
    

代码测试:

    //测试代码
        public static void main(String[] args) {
        MergesSort ms=new MergesSort();

        int a[]={8,-6,2,-7,9,-23,2,7,4,67,1,8};
        //注意第三个参数是数组的结束坐标,因为数组是从0开始的,所以结束的坐标需要数组的长度-1
        ms.mergeSort(a,0,a.length-1);
        int i=0;
        while(i<a.length){
            System.out.print(a[i++]+"  ");
        }
    }

结果:

写此博客希望以后忘记的时候能够回顾一下,代码如果有不对的地方,请大佬们指正,谢谢~

时间: 2024-11-05 06:16:50

归并排序:步骤讲解与代码实现的相关文章

二叉树的遍历方法之层序-先序-中序-后序遍历的简单讲解和代码示例

二叉树的基础性质及二叉树的建立参见前面两篇博文: http://blog.csdn.net/why850901938/article/details/51052936 http://blog.csdn.net/why850901938/article/details/51052156 首先为了讲解方便,我建立了如图所示的二叉树: 取名为:树A 1.何为层序遍历? 层序遍历就是按照二叉树的层次由上到下的进行遍历,每一层要求访问的顺序为从左到右: 以树A为例,层序遍历得到的结果为: 5 2 6 1

编程算法 - K路归并排序(k-way merge sort) 代码(C++)

K路归并排序(k-way merge sort) 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy K路归并排序作为经典的外部排序算法, 是程序员必须要掌握的. 知识概念参考: <数据结构> 主要思想: 在k个已排序的文件中, 选择第一个值, 采用败者树, 更新二叉树结构, 最终选择最优值. 代码仅供参考, 如最小值用(-1)代替, 最大值用(100)代替. /* * main.cpp * * Created on: 2014年9月11日 *

MP4视频文件过大压缩的技巧是什么?简单步骤讲解

MP4视频格式相信是大家接触的最多的一种视频格式,当我们在刷视频的时候看待一个好看的视频文件想发送给自己的好友一起观看,但传输的过程由于视频过大无法上传或者上传速度很慢的时候该怎么办呢?应该如何在不缩短视频时长的情况下将视频进行压缩呢?其实方法很简单,下面将MP4视频压缩的方法分享给大家,一起来看看吧! 操作步骤讲解: 1.首先,我们需要借助一台电脑和一个压缩工具,通过这两样来进行实现: 2.打开压缩工具,在跳转的页面有五个功能选项,点击选择视频压缩: 3.进入压缩界面,通过添加文件将需要进行压

java 简单工厂模式、多态工厂、抽像工厂 讲解, 代码示例

package org.rui.pattern2; import java.util.*; import junit.framework.*; /** * (实现 factory 模式)常用的方法是把 factory 声明为基类的静态方法(static method) * * @author Administrator * */ abstract class Shape { public abstract void draw(); public abstract void erase(); pu

卷积神经网络(CNN)讲解及代码

网上有很多关于CNN的教程讲解,在这里我们抛开长篇大论,只针对代码来谈.本文用的是matlab编写的deeplearning toolbox,包括NN.CNN.DBN.SAE.CAE.在这里我们感谢作者编写了这样一个简单易懂,适用于新手学习的代码.由于本文直接针对代码,这就要求读者有一定的CNN基础,可以参考Lecun的Gradient-Based Learning Applied to Document Recognition和tornadomeet的博文 首先把Toolbox下载下来,解压缩

微信公众平台开发详细步骤与java代码

1.微信公众平台设置 首先在https://mp.weixin.qq.com/注册一个公众平台账号(服务号.订阅号.企业号的区别) 微信公众平台地址:https://mp.weixin.qq.com 登录微信公众平台后台,在左侧列表中最下方,找到“ 基本配置 ”,点击进入 进入服务器配置填写框. 点击“修改配置”按钮 这里url需要填以下申请好的地址,tocken需要填写代码中指定好的. 2.申请服务器资源 创建新浪云计算应用 申请账号 我们使用SAE新浪云计算平台作为服务器资源,申请地址为:

在Linux上使用Wine安装轻聊版的QQ的步骤讲解

准备 Wine 环境 wine 版本要求,越新越好,我用的 1.7.55,目前最新是1.8rc2. 删除或者备份你的 ~/.wine,如果你之前运行过 wine 的话.因为涉及到少量配置,尽量不要让以前的环境干扰你. 配置 Wine运行 winecfg,在“应用程序”页签底部,“Windows版本”,选择为"8.1".8.0可能也是可以的,但我选的是8.1. 设置为 windows 8.1,打开所有外部链接,比如 qq 空间等,会使用内置的 IE 浏览器(gecko win32 引擎)

Android Socket IQ聊天软件 之 聊天气泡编码步骤讲解

之前我们说到了关于IQ聊天软件的局域网聊天测试,今天给大伙说说气泡的生成和编码,这不是第三方的东西,是自己 开发的,需要整合布局和容器来实现,其实当你看到源码后,就会觉得很简单,不信你跟着我往下看 首先说说我编程的思想,我们在一个Activity里要动态生成一个消息列表,那ListView是必不可少的容器了,这是其一 其二,我们可以清楚的知道,"我"和好友的气泡底色都是不同的,QQ的底色为:"我"为白底,好友"绿底",不过这是以前老版本的,现在的

针对dhtmlX当中的treegrid在java类当中的封装实现的步骤(后台代码)

查看API实现的方式 了解其返回值的解析方式 使用Java类进行封装并且实现返回xml的String到前台 查看API的实现方式,dhtmlx的官方文档中 <?xml version='1.0' encoding='utf-8'?> <rows parent='000125103260000300084800'> <row id='000103052220000300207475' xmlkids='1'> <cell image='305.gif'>C&l