算法實例-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算法,算法接受一对迭代 ...
随机推荐
- Web语义化
在昨天和做SEO的同学聊了一会儿,当然我没有学会搜索引擎优化的技巧和知识,但在此之前一直对HTML5中header.footer.sidebar.article等标签嗤之以鼻,觉得这个和div没有什么 ...
- Springlake-01 介绍&功能&安装
1. 简介与功能 1)Springlake 是一个企业内容平台SECP 2)是一个可配置的系统,80%内容可以配置 3)允许建立和配置垂直解决方案 4)敏捷和占用空间小,可伸缩 5)端到端的安全性与性 ...
- windows批处理总结
rem echo off 表示之后所有命令行不显示,但命令结果总是会显示的!! 不存在%ROOT_DIR% . %CUR_DIR%的变量 rem @表示命令行不显示当前行,但命令结果总是会显示的!! ...
- select2初始化默认值
之前用select2初始化默认值使用了select2('val','1'),这样做没问题,但只能用在单选上,多选的话,即使将val后面的值改成数组['0', '2']这种形式也没用. <scri ...
- 关于C#中的线程重启的问题
首先不管是C#也好,还是java也好,对于已经Abort的线程是无法再次Start的,除非是声明私有变量new一个新的线程,网上也有很多人说可以Suspend挂起线程,然后再Resume继续,但是相信 ...
- jQuery监听文本框值改变触发事件(propertychange)
完整代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...
- QQ表情动图,增加写博客的乐趣
QQ表情动图,增加写博客的乐趣 body{margin:0px;}
- 经典String str = new String("abc")内存分配问题
出自:http://blog.csdn.net/ycwload/article/details/2650059 今天要找和存储管理相关的一些知识,网上搜了半天也没有找到完善的(30%的程度都不到),没 ...
- Liferay7 BPM门户开发之41: Expando API入门
Expando 是liferay的一种自定义表格扩展的方式,从5.0就已存在 , 可以在运行时新建表格\字段\行\值. 这是一种Service Builder之外的轻量级替代扩展方式,不必像Servi ...
- KnockoutJS 3.X API 第五章 高级应用(2) 控制后代绑定
注意:这是一种高级技术,通常仅在创建可重用绑定的库时使用. 默认情况下,绑定仅影响它们应用到的元素. 但是如果你想影响所有的后代元素呢? 为此,只需从绑定的init函数中返回{controlsDesc ...