算法實例-C#-歸併排序-MergeSort
# 算法实例 #
排序算法Sort
歸併排序MergeSort
算法說明
- 歸併的思路是任意兩個元素可以比較大小,那麼任意兩個有序的元素集合也可以通過比較大小的方式歸併成一個有序的元素集合
- 任何的無序元素集合可以拆分的最小的可比較單位是元素本身,例如List list = new List() { 23, 42, 4, 16, 8, 23, 15, 3, 9, 55, 0, 23, 34, 12, 2, 46, 25, 25 };可以拆分到最小的元素為{{23},{42},{4},{16},{8},{23},{15},{3},{9},{55},{0},{23},{34},{12},{2},{46},{25},{25}},如果我們將這些元素組合兩兩比較就可以得到新的一組有序的元素組合{{23,24},{4,16},{8,23},{3,15},{9,55},{0,23},{12,34},{2,46},{25,25}}
- 對於上訴的元素集合進行比較后的有序元素集合,如下圖
最基本元素(即不可拆分最小元素集合)

第一次兩兩歸併

第二次兩兩歸併

第三次兩兩歸併

第四次兩兩歸併

最終合一的歸併

算法步驟
1.我的算法中使用隊列來作為容器容納元素,最小可比較單位也就是隊列中只有壹個元素,同時在外層也使用隊列來分別容納歸併的隊列即使用 Queue<Queue<T>> 的結構,其中 Queue<Queue<T>>是壹個歸併隊列的集合(如[{23,24},{4,16}]),Queue<T>是有序元素的集合(如{23,24})
2.遞歸的跳出條件是,歸併完成即Queue<Queue<T>>的元素個數Count為壹.且每一次遞歸完成一次兩兩歸併.
3.使用隊列的好處在於,可以使用Peek()和Dequeue()方法來確定參與一次歸併的隊列Queue<T> _tempLeft和Queue<T> _tempRight哪一個先出對歸並到新的有序集合中.
代碼示例
public static class MergeSorterA
{
/// <summary>
/// Public merge-sort API
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection"></param>
/// <param name="comparer"></param>
public static void MergeSortA<T>(this Queue<T> collection, Comparer<T> comparer = null)
{
comparer = comparer ?? Comparer<T>.Default;
Queue<Queue<T>> _queue = new Queue<Queue<T>>();
while (collection.Count !=0 )
{
Queue<T> _temp = new Queue<T>();
_temp.Enqueue(collection.Dequeue());
_queue.Enqueue(_temp);
}
_queue.InternalMergeSortA(comparer);
foreach (var item in _queue.Dequeue())
{
collection.Enqueue(item);
}
}
/// <summary>
/// Implements the recursive merge-sort algorithm
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collectionQueue"></param>
/// <param name="comparer"></param>
private static void InternalMergeSortA<T>(this Queue<Queue<T>> collectionQueue, Comparer<T> comparer)
{
Queue<Queue<T>> _listQueue = new Queue<Queue<T>>();
while (collectionQueue.Count != 0)
{
Queue<T> _queue = new Queue<T>();
Queue<T> _tempLeft = new Queue<T>();
Queue<T> _tempRight = new Queue<T>();
_tempLeft = collectionQueue.Dequeue();
//make sure _tmepLeft is not the ends
if (collectionQueue.Count != 0)
{
_tempRight = collectionQueue.Dequeue();
}
int _length = _tempLeft.Count + _tempRight.Count;
for (int i = 0; i < _length; i++)
{
if (_tempLeft.Count > 0 && _tempRight.Count > 0)
{
_queue.Enqueue(comparer.Compare(_tempLeft.Peek(), _tempRight.Peek()) <= 0 ? _tempLeft.Dequeue() : _tempRight.Dequeue());
}
else if (_tempLeft.Count > 0)
{
_queue.Enqueue(_tempLeft.Dequeue());
}
else if (_tempRight.Count > 0)
{
_queue.Enqueue(_tempRight.Dequeue());
}
}
_listQueue.Enqueue(_queue);
}
if (_listQueue.Count > 1)
{
_listQueue.InternalMergeSortA(comparer);
}
collectionQueue.Clear();
foreach (var item in _listQueue)
{
collectionQueue.Enqueue(item);
}
}
}
測試用例
[TestMethod]
public void TestMethod3()
{
List<int> list = new List<int>() { 23, 42, 4, 16, 8, 23, 15, 3, 9, 55, 0, 23, 34, 12, 2, 46, 25, 25 };
Queue<int> _queue = new Queue<int>(list);
_queue.MergeSortA();
Assert.Fail();
}
算法實例-C#-歸併排序-MergeSort的更多相关文章
- 算法實例-C#-信箱排序-PigeonHoleSort
# 算法实例 # 排序算法Sort 信箱排序PigeonHoleSort https://en.wikipedia.org/wiki/Pigeonhole_sort 算法說明 1.信箱算法使用一個完整 ...
- 七内部排序算法汇总(插入排序、Shell排序、冒泡排序、请选择类别、、高速分拣合并排序、堆排序)
写在前面: 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素的随意序列,又一次排列成一个按keyword有序的序列.因此排序掌握各种排序算法很重要. 对以下介绍的各个排序,我们假定全部排 ...
- 《算法4》2.1 - 选择排序算法(Selection Sort), Python实现
选择排序算法(Selection Sort)是排序算法的一种初级算法.虽然比较简单,但是基础,理解了有助于后面学习更高深算法,勿以勿小而不为. 排序算法的语言描述: 给定一组物体,根据他们的某种可量化 ...
- JavaScript 数据结构与算法之美 - 十大经典排序算法汇总(图文并茂)
1. 前言 算法为王. 想学好前端,先练好内功,内功不行,就算招式练的再花哨,终究成不了高手:只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 ...
- SpringMVC常用注解實例詳解3:@ResponseBody
我的開發環境框架: springmvc+spring+freemarker開發工具: springsource-tool-suite-2.9.0JDK版本: 1.6.0_29tomcat ...
- SpringMVC常用注解實例詳解2:@ModelAttribute
我的開發環境框架: springmvc+spring+freemarker開發工具: springsource-tool-suite-2.9.0JDK版本: 1.6.0_29tomcat ...
- RTX的api開發實例
RTX的api開發實例 最近接觸了RTX的接口開發部份,RTX其实有很多玩法,除了可以用自帶的客戶端發消息之外還可以用PHP調用API的方式來做一些事情,下邊整理了一下分享給大家 值得提醒的是这些接口 ...
- 簡單SQL存儲過程實例
簡單SQL存儲過程實例 摘自:http://blog.csdn.net/libra6956/article/details/5589173 实例1:只返回单一记录集的存储过程. 银行存款表(bankM ...
- C++ Primer : 第十章 : 泛型算法 之 只读、写和排序算法
大多数算法都定义在<algorithm>头文件里,而标准库还在头文件<numeric>里定义了一组数值泛型算法,比如accumulate. ● find算法,算法接受一对迭代 ...
随机推荐
- Linux多线程系列-2-条件变量的使用(线程安全队列的实现)
多线程情况下,往往需要使用互斥变量来实现线程间的同步,实现资源正确共享. linux下使用如下变量和函数 //条件变量 pthread_cond_t int pthread_cond_init (pt ...
- Http基础
Http基础 这篇文章是讲Android网络请求的先导文章,主要讲Http工作流程,请求报文和响应报文的格式,以及GET和POST方法的具体含义. Http工作流程 HTTP是一个客户端和服务器端请求 ...
- WebApi系列~通过HttpClient来调用Web Api接口~续~实体参数的传递
回到目录 上一讲中介绍了使用HttpClient如何去调用一个标准的Web Api接口,并且我们知道了Post,Put方法只能有一个FromBody参数,再有多个参数时,上讲提到,需要将它封装成一个对 ...
- Java程序员的日常 —— 注册工厂的妙用
注册工厂是一种很常用的框架书写方法,它适合于快速创建相同类型的对象. 举个栗子 比如一个家具工厂,有沙发.椅子.茶几等等,正常的编程模式是这样的: //创建 class 沙发{} class 椅子{} ...
- Atitit 从 RGB 到 HSL 或 HSV 的转换
Atitit 从 RGB 到 HSL 或 HSV 的转换 1.1. 从 RGB 到 HSL 或 HSV 的转换公式与原理1 1.2. public static HSV RGB2HSV(Color ...
- 用 flow.ci 让 Hexo 持续部署
编者按:感谢 @小小小杜 投稿,原文链接Juglans' Blog.如果你也想体验 flow.ci 的自动化持续部署,来 http://flow.ci 首页提交申请,邀请码随后会发送到邮箱:) flo ...
- spring 学习
一.spring框架介绍 Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供 ...
- C++生成二级制文件过程(预处理->编译->链接 )
转载请注明出处 Windows下C++编程,通过VC生成工程,编写C++源文件,点运行,代码没问题直接出结果.VC什么都帮我们搞了,不了解其中过程也完全没问题. 转到linux下写c++,总觉得有点虚 ...
- 快速入门系列--WebAPI--01基础
ASP.NET MVC和WebAPI已经是.NET Web部分的主流,刚开始时两个公用同一个管道,之后为了更加的轻量化(WebAPI是对WCF Restful的轻量化),WebAPI使用了新的管道,因 ...
- javase基础复习攻略《一》
作为一名软件工程专业,JAVA开发方向的大三本科学生,有必要把自己的学到的专业知识进行一下整理,一则方便自己了解自己的学习程度,二则帮助刚刚接触这一门语言的童鞋了解学习,本人来自与河南理工大学,介绍完 ...