归并排序算法(C#实现)

 归并排序(Merge Sort)是利用"归并"技术来进行排序。归并是指将若干个已排序的子文件合并成一个有序的文件。归并排序有两种方式:1): 自底向上的方法 2):自顶向下的方法

 1、 自底向上的方法
(1) 自底向上的基本思想
     自底向上的基本思想是:第1趟归并排序时,将待排序的文件R[1..n]看作是n个长度为1的有序子文件,将这些子文件两两归并,若n为偶数,则得到n/2个长度为2的有序子文件;若n为奇数,则最后一个子文件轮空(不参与归并)。故本趟归并完成后,前n/2 - 1个有序子文件长度为2,但最后一个子文件长度仍为1;第2趟归并则是将第1趟归并所得到的n/2个有序的子文件两两归并,如此反复,直到最后得到一个长度为n的有序文件为止。
     上述的每次归并操作,均是将两个有序的子文件合并成一个有序的子文件,故称其为"二路归并排序"。类似地有k(k>2)路归并排序。   

 

2、自顶向下的方法(本文主要介绍此种方法,下面的文字都是对此种方法的解读)

(1) 自顶向下的基本思想
     采用分治法进行自顶向下的算法设计,形式更为简洁。
     自顶向下的归并排序:是利用递归和分而治之的技术将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列,归并排序包括两个步骤,分别为:

      1)划分子表

      2)合并半子表


(1)分治法的三个步骤
     设归并排序的当前区间是R[low..high],分治法的三个步骤是:
①分解:将当前区间一分为二,即求分裂点
②求解:递归地对两个子区间R[low..mid]和R[mid+1..high]进行归并排序;
③组合:将已排序的两个子区间R[low..mid]和R[mid+1..high]归并为一个有序的区间R[low..high]。
  递归的终结条件:子区间长度为1(一个记录自然有序)。

如下演示递归的整个过程:

递归便是深度遍历(如下由左至右进行遍历):假设有这样的一列数组{9,8,7,6,5,4,3,2,1}进行划分的顺序如下:

{9,8,7,6,5,4,3,2,1} --> {9,8,7,6,5},{4,3,2,1}

 

{9,8,7,6,5} --> {9,8,7},{6,5}

                        {9,8,7} --> {9,8},{7}

                                          {9,8} --> {9},{8}

                        {6,5} -->{6},{5}

 

{4,3,2,1} --> {4,3},{2,1}

                      {4,3} -->{4},{3}

                      {2,1} -->{2},{1}

 

当深度划分到左右数组都只剩1个元素的时候,进行上述逆序的合并:

{9},{8} --> {8,9} 然后和 {7} --> {7,8,9}

                                {6},{5} --> {5,6}    然后 {7,8,9}和{5,6} --> {5,6,7,8,9}

                                     {2},{1} --> {1,2}

                                     {4},{3} --> {3,4}   然后 {1,2}和 {3,4} --> {1,2,3,4}

                                                                                                                         最终{5,6,7,8,9}和{1,2,3,4} --> {1,2,3,4,5,6,7,8,9}

 

具体实现代码如下所示:

复制代码
        //归并排序(目标数组,子表的起始位置,子表的终止位置)
private static void MergeSortFunction(int[] array, int first, int last)
{
try
{
if (first < last) //子表的长度大于1,则进入下面的递归处理
{
int mid = (first + last) / 2; //子表划分的位置
MergeSortFunction(array, first, mid); //对划分出来的左侧子表进行递归划分
MergeSortFunction(array, mid + 1, last); //对划分出来的右侧子表进行递归划分
MergeSortCore(array, first, mid, last); //对左右子表进行有序的整合(归并排序的核心部分)
}
}
catch (Exception ex)
{ }
}

//归并排序的核心部分:将两个有序的左右子表(以mid区分),合并成一个有序的表
private static void MergeSortCore(int[] array, int first, int mid, int last)
{
try
{
int indexA = first; //左侧子表的起始位置
int indexB = mid + 1; //右侧子表的起始位置
int[] temp = new int[last + 1]; //声明数组(暂存左右子表的所有有序数列):长度等于左右子表的长度之和。
int tempIndex = 0;
while (indexA <= mid && indexB <= last) //进行左右子表的遍历,如果其中有一个子表遍历完,则跳出循环
{
if (array[indexA] <= array[indexB]) //此时左子表的数 <= 右子表的数
{
temp[tempIndex++] = array[indexA++]; //将左子表的数放入暂存数组中,遍历左子表下标++
}
else//此时左子表的数 > 右子表的数
{
temp[tempIndex++] = array[indexB++]; //将右子表的数放入暂存数组中,遍历右子表下标++
}
}
//有一侧子表遍历完后,跳出循环,将另外一侧子表剩下的数一次放入暂存数组中(有序)
while (indexA <= mid)
{
temp[tempIndex++] = array[indexA++];
}
while (indexB <= last)
{
temp[tempIndex++] = array[indexB++];
}

//将暂存数组中有序的数列写入目标数组的制定位置,使进行归并的数组段有序
tempIndex = 0;
for (int i = first; i <= last; i++)
{
array[i] = temp[tempIndex++];
}
}
catch (Exception ex)
{ }
}
复制代码



 

       对于N个元素的数组来说, 如此划分需要的层数是以2为底N的对数, 每一层中, 每一个元素都要复制到结果数组中, 并复制回来, 所以复制2N次, 那么对于归并排序,它的时间复杂度为O(N*logN), 而比较次数会少得多, 最少需要N/2次,最多为N-1次, 所以平均比较次数在两者之间. 它的主要问题还是在于在内存中需要双倍的空间.

转载于:https://www.cnblogs.com/kloseking/p/3165710.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/421659.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

m5310采用芯片 中移物联_芯链HPB引领硬件区块链加密芯片技术,有望在谷歌光芯之前突破...

伴随人工智能时代的开启&#xff0c;世界对于高性能计算机器的需求磅礴发展&#xff1b;以往的高性能计算芯片是基于CMOS数字电路的处理器&#xff0c;而伴随着电子元件的摩尔定律接近技术瓶颈&#xff0c;数字电路芯片的发展速度和发展基础都在缓慢进行&#xff1b;区块链技术…

计算机的硬件工作原理(图片部分资源摘自王道考研资料)

一、现代计算机的组成 此处主存和辅存可以理解为&#xff0c;内存和外存&#xff0c;内存的特点是读取速度快但是不利于保存大量数据&#xff0c;外存的特点 是读取速度慢&#xff0c;但是可以存储大量数据 计算机在开机时不会读取硬盘上的所有数据&#xff0c;开机时先读取的…

rstp协议和stp协议对比_3.TCP和UDP协议对比

TCP、UDP协议对比任务&#xff1a;掌握TCP协议、UDP协议的作用&#xff1b;TCP的三次握手和四次挥手&#xff1b;RST断开连接过程和作用。1.TCPTCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;由IETF的RFC …

计算机组成原理-数据的表示和运算(图片资源摘自王道考研资料)

一、进位计数制 二、BCD码 此处&#xff1a; 58 0101 1000 1101 超出数据能表达的范围&#xff0c;因为 8421码只能表示0-9 十以上数据视为无效数据&#xff0c;因此在此基础上加六&#xff0c;进行校正--> 11010110 0001 0011 ----拆成两个看

lacp可以在access接口吗_现网必用的链路冗余技术,静态LACP链路捆绑,两分钟快速掌握...

一、链路聚合链路聚合(Link Aggregation)是将—组物理接口捆绑在一起作为一个逻辑接口来增加带宽的一种方法&#xff0c;又称为多接口负载均衡组(Load Sharing Group)或链路聚合组(Link Aggregation Group)1、配置手工负载分担模式链路聚合手工负载分担模式下&#xff0c;Eth-T…

Spring 集成web环境

Spring 集成web环境 一、配置ContextLoaderListener 监听器 1.maven坐标 org.springframework spring-web 5.3.14 2.web.xml <context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</para…

一只青蛙跳向三个台阶_8. 跳台阶

一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。1. 思路&#xff1a;若只有一级台阶&#xff1a;一种跳法两级台阶&#xff1a;两种跳法(11 / 2)三级台阶&#xff1a;三种跳法(111 / 12 / 21)四级台阶&#xff1a;五种跳法…

spring 框架(一)

目录 一、spring简介 二、spring入门 三、spring配置文件 3.1.bean标签的基本配置(applicationContext.xml) 3.2Bean&#xff08;scope:指对象的作用范围&#xff09;标签范围配置 3.3 Bean生命周期配置 3.4 Bean实例化三种方式 3.5 Bean的依赖注入入门 3.6 Bean的依赖…

cdr添加节点快捷键_CDR快捷键分享,需要的赶紧收藏!

点击上方蓝字&#xff0c;关注我们哦&#xff01;&#xff01;有粉丝在后台留言说&#xff0c;希望我分享一下CDR的快捷键&#xff0c;今天我整理了一下快捷键。来源&#xff1a;内容整理自网络&#xff0c;仅供学习交流一工具箱I 绘制曲线&#xff0c;并对笔划使用预置、画刷、…

spring 框架(二)

目录 一、Spring配置数据源 1.1 数据源(连接池)的作用 1.2数据源的使用 1.3基本实现 1.4.抽取配置文件&#xff0c;降低耦合性(druid) 1.4.1抽取jdbc.properties文件 1.4.2设置数据源的基本连接数据&#xff0c;通过applicationContext.xml设置数据库参数applicationCon…

matplotlib 对称图_Python 绘图,我只用 Matplotlib

散点图散点图显示两组数据的值&#xff0c;如图1-1所示。每个点的坐标位置由变量的值决定&#xff0c;并由一组不连接的点完成&#xff0c;用于观察两种变量的相关性。例如&#xff0c;身高—体重、温度—维度。图1-1 散点图示例使用Matplotlib的scatter()函数绘制散点图&#…

spring框架(三)mvc

目录 1.1准备测试数据 1.2 ApplicationContext应用上下文获取方式 1.2.1添加listener包 1.2.2解耦配置文件 1.2.3 继续提取ContextLoaderListener.java中参数app 1.2.4 Spring提供获取应用上下文的工具 二、SpringMVC 2.1概述 2.2数据准备 2.3添加success.jsp页面 2.4 …

python判断字符串中包含某个字符串_干货分享| Python中最常用的字符串方法

字符串是字符序列。Python中内置的string类代表基于Unicode国际字符集的字符串。除了Python中常见的操作外,字符串还有一些专属于它们的附加方法。下图显示了所有这些可用的方法: Python中的内置字符串函数 在本文中,我们将学习一些最常用的方法。这里需要注意的重要一点是,…

spring (四) SpringMVC的请求和响应

目录 前言 一、SpringMVC的数据响应 1.1 SpringMVC的数据响应方式 1.1.1页面跳转 直接返回字符串 ​ 1.1.2通过ModelAndView对象返回 1.2 回写数据 1.2.1直接返回字符串 1.2.2返回对象或集合 二、SpringMVC获得请求数据 2.1 获得请求参数 2.2 获得基本类型…

拼接路径优雅方式_中年女人最好少穿马丁靴,简约的“无痕靴”更适合你,优雅高级...

女人在到了中年的时候&#xff0c;经过很多世事的沉淀&#xff0c;气质也会变得更加的淡定与从容。在穿搭上面&#xff0c;也不会喜欢像小姑娘那般的去盲目地追求潮流&#xff0c;跟风一些并不适合自己穿搭的服装&#xff0c;强行的装嫩的话&#xff0c;也会显得有些尴尬。中年…