DotNet常用排序算法总结
数据结构和算法对一个程序来说是至关重要的,现在介绍一下几种算法,在项目中较为常用的算法有:冒泡排序,简单选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序等7中算法。
现在介绍选择排序算法,希尔排序算法,快速排序算法。
(1).选择排序算法:通过n-i次关键字间的比较,从n-i+1个记录中选择出关键字最小的记录,并和第i(1大于等于i小于等于n)个记录交换。
(2).希尔排序:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量
=1(
<
…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
(3).快速排序算法:通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。
以上是对算法定义的简单说明,接下来看看算法的具体实现:
1.排序算法类型的接口:
/// <summary>
/// 排序算法类型的接口
/// </summary>
internal interface ISortAlgorithm
{
/// <summary>
/// 按指定的方向对指定的列表进行排序。
/// </summary>
/// <typeparam name="T">要排序的元素的类型</typeparam>
/// <param name="toSort">要排序的列表</param>
/// <param name="direction">排序方向</param>
/// <param name="startIndex">开始索引</param>
/// <param name="endIndex">结束开始索引</param>
/// <param name="compareFunc">比较功能。</param>
void Sort<T>(IList<T> toSort, SortDirection direction, int startIndex, int endIndex, Comparison<T> compareFunc);
}
2.排序算法工厂类:
/// <summary>
///排序算法工厂类
/// </summary>
internal static class SortAlgorithmFactory
{
/// <summary>
/// 创建排序算法实现。
/// </summary>
/// <param name="algorithm">算法</param>
/// <returns></returns>
internal static ISortAlgorithm CreateSortAlgorithmImplementation(SortAlgorithm algorithm)
{
ISortAlgorithm toReturn = null; switch (algorithm)
{
case SortAlgorithm.SelectionSort:
toReturn = new SelectionSorter();
break;
case SortAlgorithm.ShellSort:
toReturn = new ShellSorter();
break;
case SortAlgorithm.QuickSort:
toReturn = new QuickSorter();
break;
} return toReturn;
}
}
3.快速排序算法 :
/// <summary>
/// 快速排序算法
/// </summary>
internal class QuickSorter : ISortAlgorithm
{
/// <summary>
/// 按指定的方向对指定的列表进行排序。
/// </summary>
/// <typeparam name="T">要排序的元素的类型</typeparam>
/// <param name="toSort">要排序的列表。</param>
/// <param name="direction">在侵权行为中排序元素的方向。</param>
/// <param name="startIndex">开始索引。</param>
/// <param name="endIndex">结束索引。</param>
/// <param name="compareFunc">比较功能。</param>
void ISortAlgorithm.Sort<T>(IList<T> toSort, SortDirection direction, int startIndex, int endIndex, Comparison<T> compareFunc)
{
Func<T, T, bool> valueComparerTest;
switch (direction)
{
case SortDirection.Ascending:
valueComparerTest = (a, b) => (compareFunc(a, b) < );
break;
case SortDirection.Descending:
valueComparerTest = (a, b) => (compareFunc(a, b) > );
break;
default:
throw new ArgumentOutOfRangeException("direction", "Invalid direction specified, can't craete value comparer func");
} PerformSort(toSort, startIndex, endIndex, valueComparerTest);
} /// <summary>
/// 在列表中执行分区的排序,这个例程被递归调用。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="toSort">排序。</param>
/// <param name="left">左索引。</param>
/// <param name="right">正确的索引。</param>
/// <param name="valueComparerTest">值比较器测试。</param>
private static void PerformSort<T>(IList<T> toSort, int left, int right, Func<T, T, bool> valueComparerTest)
{
while (true)
{
if (right <= left)
{
return;
}
var pivotIndex = Partition(toSort, left, right, left, valueComparerTest);
PerformSort(toSort, left, pivotIndex - , valueComparerTest);
left = pivotIndex + ;
}
} /// <summary>
///分区指定的列表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="toSort">排序。</param>
/// <param name="left">左边。</param>
/// <param name="right">右边</param>
/// <param name="pivotIndex">枢轴索引。</param>
/// <param name="valueComparerTest">值比较器测试。</param>
/// <returns>新枢纽点的索引</returns>
private static int Partition<T>(IList<T> toSort, int left, int right, int pivotIndex, Func<T, T, bool> valueComparerTest)
{
var pivotValue = toSort[pivotIndex];
toSort.SwapValues(pivotIndex, right);
var storeIndex = left;
for (var i = left; i < right; i++)
{
if (!valueComparerTest(toSort[i], pivotValue))
{
continue;
}
toSort.SwapValues(i, storeIndex);
storeIndex++;
}
toSort.SwapValues(storeIndex, right);
return storeIndex;
}
}
4.希尔排序算法:
/// <summary>
///希尔排序算法
/// </summary>
internal class ShellSorter : ISortAlgorithm
{
/// <summary>
/// 按指定的方向对指定的列表进行排序。
/// </summary>
/// <typeparam name="T">要排序的元素的类型</typeparam>
/// <param name="toSort">要排序的列表</param>
/// <param name="direction">排序方向</param>
/// <param name="startIndex">开始索引</param>
/// <param name="endIndex">结束开始索引</param>
/// <param name="compareFunc">比较功能。</param>
void ISortAlgorithm.Sort<T>(IList<T> toSort, SortDirection direction, int startIndex, int endIndex, Comparison<T> compareFunc)
{
Func<T, T, bool> valueComparerTest;
switch (direction)
{
case SortDirection.Ascending:
valueComparerTest = (a, b) => (compareFunc(a, b) > );
break;
case SortDirection.Descending:
valueComparerTest = (a, b) => (compareFunc(a, b) < );
break;
default:
throw new ArgumentOutOfRangeException("direction", "Invalid direction specified, can't craete value comparer func");
} int[] increments = { , , , , , , , , , , , , , , , };
for (var incrementIndex = ; incrementIndex < increments.Length; incrementIndex++)
{
for (int intervalIndex = increments[incrementIndex], i = startIndex + intervalIndex; i <= endIndex; i++)
{
var currentValue = toSort[i];
var j = i;
while ((j >= intervalIndex) && valueComparerTest(toSort[j - intervalIndex], currentValue))
{
toSort[j] = toSort[j - intervalIndex];
j -= intervalIndex;
}
toSort[j] = currentValue;
}
}
}
}
5.选择排序算法:
/// <summary>
/// 选择排序算法
/// </summary>
internal class SelectionSorter : ISortAlgorithm
{
/// <summary>
/// 按指定的方向对指定的列表进行排序。
/// </summary>
/// <typeparam name="T">要排序的元素的类型</typeparam>
/// <param name="toSort">要排序的列表。</param>
/// <param name="direction">在侵权行为中排序元素的方向。</param>
/// <param name="startIndex">开始索引。</param>
/// <param name="endIndex">结束索引。</param>
/// <param name="compareFunc">比较功能。</param>
void ISortAlgorithm.Sort<T>(IList<T> toSort, SortDirection direction, int startIndex, int endIndex, Comparison<T> compareFunc)
{
Func<T, T, bool> valueComparerTest;
switch (direction)
{
case SortDirection.Ascending:
valueComparerTest = (a, b) => (compareFunc(a, b) > );
break;
case SortDirection.Descending:
valueComparerTest = (a, b) => (compareFunc(a, b) < );
break;
default:
throw new ArgumentOutOfRangeException("direction", "指定的方向无效,无法创建值比较器函数");
} for (var i = startIndex; i < endIndex; i++)
{
var indexValueToSwap = i;
for (var j = i + ; j <= endIndex; j++)
{
if (valueComparerTest(toSort[indexValueToSwap], toSort[j]))
{
indexValueToSwap = j;
}
}
toSort.SwapValues(i, indexValueToSwap);
}
}
}
以上的算法实现中,采用了简单工厂模式,实现算法的松耦合。
简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。简单工厂模式包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。
简单工厂的UML图如下:

如果需要增加新的算法,在添加完新的算法实现类后,可直接在工厂方法中添加case分支,无需在客户端更改类,只需要在子类中选择实现类即可。
DotNet常用排序算法总结的更多相关文章
- Java常用排序算法+程序员必须掌握的8大排序算法+二分法查找法
Java 常用排序算法/程序员必须掌握的 8大排序算法 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排 ...
- 转载部长一篇大作:常用排序算法之JavaScript实现
转载部长一篇大作:常用排序算法之JavaScript实现 注:本文是转载实验室同门王部长的大作,找实习找工作在即,本文颇有用处!原文出处:http://www.cnblogs.com/ywang172 ...
- Java 常用排序算法/程序员必须掌握的 8大排序算法
Java 常用排序算法/程序员必须掌握的 8大排序算法 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排序(直接选择排序.堆排序) 4)归并排序 5)分配 ...
- 常用排序算法的python实现和性能分析
常用排序算法的python实现和性能分析 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试 ...
- 面试中常用排序算法实现(Java)
当我们进行数据处理的时候,往往需要对数据进行查找操作,一个有序的数据集往往能够在高效的查找算法下快速得到结果.所以排序的效率就会显的十分重要,本篇我们将着重的介绍几个常见的排序算法,涉及如下内容: 排 ...
- 常用排序算法java实现
写在前面:纸上得来终觉浅.基本排序算法的思想,可能很多人都说的头头是到,但能说和能写出来,真的还是有很大区别的. 今天整理了一下各种常用排序算法,当然还不全,后面会继续补充.代码中可能有累赘或错误的地 ...
- 我们一起来排序——使用Java语言优雅地实现常用排序算法
破阵子·春景 燕子来时新社,梨花落后清明. 池上碧苔三四点,叶底黄鹂一两声.日长飞絮轻. 巧笑同桌伙伴,上学径里逢迎. 疑怪昨宵春梦好,元是今朝Offer拿.笑从双脸生. 排序算法--最基础的算法,互 ...
- Python实现常用排序算法
Python实现常用排序算法 冒泡排序 思路: 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完 ...
- 第四百一十五节,python常用排序算法学习
第四百一十五节,python常用排序算法学习 常用排序 名称 复杂度 说明 备注 冒泡排序Bubble Sort O(N*N) 将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮 ...
随机推荐
- 【http代理报文】通过发包实现代理请求网页内容
工作中,我们难免需要通过TCP/IP协议发送报文来直接请求网页内容(比如爬虫工具),有同学问如何通过HTTP代理来请求网页,其实我们只需要把报文稍稍修改下,发送给代理服务器即可实现. 基础不过关的朋友 ...
- 搬-Android - Wi-Fi Tutorial[转]
http://www.tutorialspoint.com/android/android_wi_fi.htm Android allows applications to access to vie ...
- 谢欣伦 - OpenDev原创教程 - 媒体开发库libMedia
libMedia是一个免费的简单的媒体开发库,其中的接口类与函数大都以小写的x打头,来源于我的姓氏首字母(谢欣伦). 下载 OpenDev for VS2012 libMedia提供四大功能,一是视频 ...
- 谢欣伦 - 原创软件 - 游戏专题 - 我的桌面My Desktop
今天在网上看到一个用桌面背景当做拼图内容的游戏很新颖,反正今天下雨我也闲着,索性用了半天时间做了一个类似的游戏<MyDesktop>.做完后立即分享给了两个朋友,他俩都被吓坏了.现在分享给 ...
- MySQL 注册码
最近开发是用MySQL数据库,之前安装后,每次打开Navicat Premium 都提示 “试用一个月”,“ 注册”,然后为了方便,就都选择了 试用的, 一个月后,就必须的输入注册码,(还有一个是 什 ...
- Redis 集群的合纵与连横
之前一篇写了关于 Redis 的性能,这篇就写写我认为比性能更重要的扩展性方面的主题. 如果再给我一次回到好几年前的机会,对于使用 Redis 我一开始就要好好考虑将来的扩展问题.就像我们做数据库分库 ...
- 安卓动态调试七种武器之离别钩 – Hooking(下)
0x00 序 随着移动安全越来越火,各种调试工具也都层出不穷,但因为环境和需求的不同,并没有工具是万能的.另外工具是死的,人是活的,如果能搞懂工具的原理再结合上自身的经验,你也可以创造出属于自己的调试 ...
- Windows建立Cucumber和Ruby测试环境
1. 下载安装Ruby1.9.3, 不要用RubyInstall 一键安装,下载zip然后解压到c:\Ruby193 (不要用2.0,用2.0安装不成功,不要怪我) 2. 环境变量配置RUBY_HOM ...
- [Voice communications] 声道的转换
本系列文章主要是介绍 Web Audio API 的相关知识,以及 web语音通信 中会遇到的一些问题,阐述可能存在错误,还请多多斧正! 很多粤语剧都提供了两个声道,一个左声道为粤语,一个右声道有国语 ...
- Mac下设置Android源代码编译环境
在Mac下编译Android最麻烦的就是设置Android的编译环境了,做完这一步基本上剩下的就是近乎傻瓜式的操作了.说起来也简单就三步,设置大小写敏感的文件系统.安装编译工具.设置文件系统同时能打开 ...