1.介绍

归并排序(MergeSort)是利用归并的思想实现的排序方法,该算法采用经典的分治策略(分治法将问题分(divide)成一些小的问题然后递归求解,

而治(conquer)的阶段则将分的阶段得到的各答案“修补”在一起,即分而治之)

2.示意图

 说明:可以看到这种结构很像一颗完全二叉树,可以采用递归和循环迭代的方式去实现,分阶段可以理解为就是递归拆分子序列的过程

合并相邻有序子序列

再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,

要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤

 

3.实例

把数组[8,4,5,7,1,3,6,2]使用归并排序完成排序

    public class MergeSort
{
public static void Test()
{
int[] arr = { , , , , , , , }; int[] temp = new int[arr.Length]; Sort(arr,,arr.Length-,temp); Console.WriteLine(string.Join(",",arr));
} /// <summary>
/// 分+合方法
/// </summary>
/// <param name="arr"></param>
/// <param name="left"></param>
/// <param name="right"></param>
/// <param name="temp"></param>
private static void Sort(int[] arr,int left,int right,int[] temp)
{
if (left<right)
{
//中间索引
int mid = (left + right) / ; //向左递归进行分解
Sort(arr, left, mid, temp); //向右递归进行分解
Sort(arr, mid + , right, temp); //到合并
Merge(arr,left,mid,right,temp);
}
} /// <summary>
/// 合并方法
/// </summary>
/// <param name="arr">排序的原始数组</param>
/// <param name="left">左边有序序列的初始索引</param>
/// <param name="mid">中间索引</param>
/// <param name="right">右边索引</param>
/// <param name="temp">做中转数组</param>
private static void Merge(int[] arr, int left, int mid, int right, int[] temp)
{
int i = left; //初始化i,左边有序序列的初始化索引 int j = mid + ; //初始化j,右边有序序列的初始化索引 int t = ; //指向temp数组的当前索引 //(一)
//先把左右两边(有序)的数据按照规则填充到temp数组
//直到左右两边的有序序列,有一边处理完成为止
while (i <= mid && j <= right)
{
//如果左边的有序序列的当前元素,小于或者等于右边有序序列的当前元素
//即将左边的当前元素,填充到temp数组
//然后t++,i++
if (arr[i] <= arr[j])
{
temp[t] = arr[i]; t += ; i += ;
}
//反之,将右边有序序列的当前元素,填充到temp数组
else
{
temp[t] = arr[j]; t++; j++;
}
}
//(二)
//把有剩余数据的一边的数据依次全部填充到temp
while (i <= mid)
{
//左边的有序序列还有剩余的元素,就全部填充到temp
temp[t] = arr[i]; t++; i++;
} while (j <= right)
{
temp[t] = arr[j]; t++; j++;
}
//(三)
//将temp数组的元素拷贝到arr,并不是每次都拷贝所有
t = ; int tempLeft = left; while (tempLeft <= right) //第一次合并 tempLeft=0,right=1 第二次 tempLeft=2 right=3;
{
arr[tempLeft] = temp[t]; t++; tempLeft++;
} }
}

结果图

C#数据结构与算法系列(二十三):归并排序算法(MergeSort)的更多相关文章

  1. WPF入门教程系列二十三——DataGrid示例(三)

    DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...

  2. Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十三】

    <Web 前端开发精华文章推荐>2014年第2期(总第23期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  3. 【数据结构】 最小生成树(二)——kruskal算法

    上一期说完了什么是最小生成树,这一期咱们来介绍求最小生成树的算法:kruskal算法,适用于稀疏图,也就是同样个数的节点,边越少就越快,到了数据结构与算法这个阶段了,做题靠的就是速度快,时间复杂度小. ...

  4. CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现

    CRC16算法系列文章: CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CR ...

  5. 数据结构与算法系列----最小生成树(Prim算法&amp;Kruskal算法)

     一:Prim算法       1.概览 普里姆算法(Prim算法).图论中的一种算法.可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中.不但包含了连通图里的全部顶点(英语:Ve ...

  6. 四、排序算法总结二(归并排序)(C++版本)

    一.什么是归并排序? 归并排序是基于分而治之的思想建立起来的. 所谓的分而治之,也就是将一个数据规模为N的数据集,分解为两个规模大小差不多的数据集(n/2),然而分别处理这两个更小的问题,就相当于解决 ...

  7. JVM系列二(垃圾收集算法).

    一.标记-清除算法(Mark-Sweep) 这种算法分为"标记"和"清除"两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象. Mar ...

  8. Python排序算法(六)——归并排序(MERGE-SORT)

    有趣的事,Python永远不会缺席! 如需转发,请注明出处:小婷儿的python https://www.cnblogs.com/xxtalhr/p/10800699.html 一.归并排序(MERG ...

  9. 排序算法系列:选择排序算法JAVA版(靠谱、清晰、真实、可用、不罗嗦版)

    在网上搜索算法的博客,发现一个比较悲剧的现象非常普遍: 原理讲不清,混乱 啰嗦 图和文对不上 不可用,甚至代码还出错 我总结一个清晰不罗嗦版: 原理: 从数组头元素索引i开始,寻找后面最小的值(比i位 ...

  10. JVM-GC算法(二)-复制算法&&标记整理算法

    这次我和各位分享GC最后两种算法,复制算法以及标记/整理算法.上一篇在讲解标记/清除算法时已经提到过,这两种算法都是在此基础上演化而来的,究竟这两种算法优化了之前标记/清除算法的哪些问题呢? 复制算法 ...

随机推荐

  1. elk3

    视频来自: bootstrap.memory_lock要设置为true,默认使用物理内存 mini_mum_nodes:1表示es集群中最小的matser节点数目,默认就是1,当es集群数目较少的时候 ...

  2. JavaWeb网上图书商城完整项目--day02-27.查询所有分类功能之Servlet和Service层

    我们在上面实现了数据库层的代码,现在我们来实现业务层和Servlet层的代码:业务层的代码如下: package com.weiyuan.goods.category.service; import ...

  3. linux 在指定文件夹下查找指定字符

    grep -r '119090610015743205' /data/html/www/gap_bz_middleware/storage/apiLogs/

  4. vue全家桶(4.3)

    5.3.Vuex的核心概念 store: 每一个 Vuex 应用的核心就是 store(仓库)."store"基本上就是一个容器,它包含着你的应用中大部分的状态 (state) s ...

  5. 双缓冲显示字幕(卡拉ok字幕)

    思路: 1.设置定时器SetTime,在Ontime()里面确定显示矩形的大小,让后用DrawText把字铁道矩形上面: 2. int nTextHei = dc.GetTextExtent( m_s ...

  6. asp.net Core依赖注入(自带的IOC容器)

    今天我们主要讲讲如何使用自带IOC容器,虽然自带的功能不是那么强大,但是胜在轻量级..而且..不用引用别的库. 在新的ASP.NET Core中,大量的采用了依赖注入的方式来编写代码. 比如,在我们的 ...

  7. JavaScript中bool类型的转化

    JavaScript 中 if() 圆括号中的表达式将被看做布尔值来处理.这时就涉及到一些转化的问题. 1.特殊值undefined和null变成false. 2.数字0和NaN变成false. 3. ...

  8. Pytest 单元测试框架标记用例

    1.Pytest 中标记用例 接参数 -k 来挑选要执行的测试项 pytest -k test_szdcs -s test_szdcs 为函数名称 -k 后面接的名称可以为函数名称.类名称.文件名称. ...

  9. 新技术新框架不断涌现,目前学习web前端开发都要掌握什么?

    web前端开发由网页制作演变而来,随着web2.0的发展,网页不再只是承载单一的文字和图片,各种丰富媒体让网页的内容更加生动,网页上软件化的交互形式为用户提供了更好的使用体验,这些都是基于前端技术实现 ...

  10. python使用selenium和requests.session登录抓取

    # Author:song from selenium import webdriver from selenium.webdriver.common.keys import Keys from re ...