算法实例-C#-快速排序-QuickSort
算法实例
##排序算法Sort##
### 快速排序QuickSort ###
bing搜索结果
http://www.bing.com/knows/search?q=%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95&mkt=zh-cn&FORM=BKACAI
*使用队列*
QuickSort排序中其实最贴近人类思考方式的实现是利用队列技术
1.建立左右队列
2.遍历List,小于Pivot的放入左队列,大于等于Pivot的放入右队列
3.左队列出队+Pivot+右队列出队 构造成一个第一次排序的List
4.左队列重复步骤123,右队列重复123
5.跳出循环的条件是队列为空
*使用指针对*
1.将List尾部的元素設置為pivot
2.設置一對指針,其中wallIndex指針標誌小於pivot的數,循環指針標誌遍歷的位置
3.Note:關鍵算法在於List中想要比較移動元素需要兩組指針,wallIndex用於定位需要插入的位置,循環指針用於遍歷元素.
4.但是以文中算法其實是QuickSort的變種模式,如圖我們如果以List最後的元素作為pivot的話,第一次排序結果因該是{49 38 13 27}49{65 97 76} 但是實際使用的排序算法導致的結果應該為 {49 38 13 27}49{76 65 97}
5.使用變種的算法優勢在於使用的一對指針,實際減少了內存的使用和交換的開銷
6.如果使用隊列技術,實際上額外使用了兩塊內存空間,但是其優勢在于可以更加的貼近人類的思維習慣
### 代碼展示 ###
#### 使用指針對 ####
https://github.com/aalhour/C-Sharp-Algorithms/blob/master/Algorithms/Sorting/QuickSorter.cs
/// <summary>
///
/// </summary>
public static class QuickSorter
{
/// <summary>
/// The public APIs for the quick sort algorithm.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection"></param>
/// <param name="comparer"></param>
public static void QuickSort<T>(this IList<T> collection, Comparer<T> comparer = null)
{
int startIndex = 0;
int endIndex = collection.Count - 1;
// If the comparer is Null, then initialize it using a default typed comparer
comparer = comparer ?? Comparer<T>.Default;
collection.InternalQuickSort(startIndex, endIndex, comparer);
}
/// <summary>
/// The recursive quick sort algorithm
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection"></param>
/// <param name="leftmostIndex"></param>
/// <param name="rightmostIndex"></param>
/// <param name="comparer"></param>
private static void InternalQuickSort<T>(this IList<T> collection, int leftmostIndex, int rightmostIndex, Comparer<T> comparer)
{
// Recursive call check
if (leftmostIndex < rightmostIndex)
{
int wallIndex = collection.InternalPartition(leftmostIndex, rightmostIndex, comparer);
collection.InternalQuickSort(leftmostIndex, wallIndex - 1, comparer);
collection.InternalQuickSort(wallIndex + 1, rightmostIndex, comparer);
}
}
// The partition function, used in the quick sort algorithm
/// <summary>
/// The partition function, used in the quick sort algorithm
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection"></param>
/// <param name="leftmostIndex"></param>
/// <param name="rightmostIndex"></param>
/// <param name="comparer"></param>
/// <returns></returns>
private static int InternalPartition<T>(this IList<T> collection, int leftmostIndex, int rightmostIndex, Comparer<T> comparer)
{
int wallIndex, pivotIndex;
// Choose the pivot
pivotIndex = rightmostIndex;
T pivotValue = collection[pivotIndex];
// Compare remaining array elements against pivotValue
wallIndex = leftmostIndex;
// Loop until pivot: exclusive!
for (int i = leftmostIndex; i <= (rightmostIndex - 1); i++)
{
// check if collection[i] <= pivotValue
if (comparer.Compare(collection[i], pivotValue) <= 0)
{
collection.Swap(i, wallIndex);
wallIndex++;
}
}
collection.Swap(wallIndex, pivotIndex);
return wallIndex;
}
}
#### 使用隊列 ####
/// <summary>
/// using Queue for quick sort
/// </summary>
public static class QuickSorterA
{
public static void QuickSortA<T>(this IList<T> collection, Comparer<T> comparer = null)
{
// If the comparer is Null, then initialize it using a default typed comparer
comparer = comparer ?? Comparer<T>.Default;
Queue<T> _queue = new Queue<T>(collection);
_queue.InternalQuickSortA(comparer);
collection.Clear();
foreach (var item in _queue)
{
collection.Add(item);
}
}
private static void InternalQuickSortA<T>(this Queue<T> collection, Comparer<T> comparer)
{
if (collection.Count <=0)
{
return;
}
// Recursive call check
Queue<T> _leftQueue = new Queue<T>();
Queue<T> _rightQueue = new Queue<T>();
T _povit = collection.Dequeue();
foreach (var item in collection)
{
if (comparer.Compare(item, _povit) <= 0)
{
_leftQueue.Enqueue(item);
}
else
{
_rightQueue.Enqueue(item);
}
}
_leftQueue.InternalQuickSortA<T>(comparer);
_rightQueue.InternalQuickSortA<T>(comparer);
collection.Clear();
foreach (var item in _leftQueue)
{
collection.Enqueue(item);
}
collection.Enqueue(_povit);
foreach (var item in _rightQueue)
{
collection.Enqueue(item);
}
}
}
測試用例
[TestMethod]
public void TestMethod1()
{
List<long> list = new List<long>() { 23, 42, 4, 16, 8, 15, 3, 9, 55, 0, 34, 12, 2, 46, 25 };
list.QuickSort();
List<long> listA = new List<long>() { 23, 42, 4, 16, 8, 15, 3, 9, 55, 0, 34, 12, 2, 46, 25 };
listA.QuickSortA();
}
算法实例-C#-快速排序-QuickSort的更多相关文章
- 排序算法四:快速排序(Quicksort)
快速排序(Quicksort),因其排序之快而得名,虽然Ta的平均时间复杂度也是O(nlgn),但是从后续仿真结果看,TA要比归并排序和堆排序都要快. 快速排序也用到了分治思想. (一)算法实现 pr ...
- 小小c#算法题 - 6 - 快速排序 (QuickSort)
快速排序是排序算法中效率比较高的一种,也是面试常被问到的问题. 快速排序(Quick Sort)是对冒泡排序的一种改进.它的基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字 ...
- 快速排序(quicksort)算法实现
快速排序(quicksort)是分治法的典型例子,它的主要思想是将一个待排序的数组以数组的某一个元素X为轴,使这个轴的左侧元素都比X大,而右侧元素都比X小(从大到小排序).然后以这个X在变换后数组的位 ...
- 归并排序(MergeSort)和快速排序(QuickSort)的一些总结问题
归并排序(MergeSort)和快速排序(QuickSort)都是用了分治算法思想. 所谓分治算法,顾名思义,就是分而治之,就是将原问题分割成同等结构的子问题,之后将子问题逐一解决后,原问题也就得到了 ...
- javascript常用经典算法实例详解
javascript常用经典算法实例详解 这篇文章主要介绍了javascript常用算法,结合实例形式较为详细的分析总结了JavaScript中常见的各种排序算法以及堆.栈.链表等数据结构的相关实现与 ...
- 快速排序(QuickSort)
1.算法思想 快速排序是一种划分交换排序.它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod). (1) 分治法的基本思想 分治法的基本思想是:将原 ...
- json数据中的某一个字段进行快速排序quicksort
快速排序(Quicksort)是对冒泡排序的一种改进,是一种分而治之算法归并排序的风格. 核心的思想就是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小 ...
- 排序算法-Java实现快速排序算法
- Adaboost 算法实例解析
Adaboost 算法实例解析 1 Adaboost的原理 1.1 Adaboost基本介绍 AdaBoost,是英文"Adaptive Boosting"(自适应增强)的缩写,由 ...
随机推荐
- 跨站脚本攻击XSS
跨站脚本攻击(Cross Site Script为了区别于CSS简称为XSS)指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到 ...
- 腾讯Ubuntu云虚拟主机设置ftp服务器
刚申请了免费的腾讯云主机, 发现还要想办法自己的服务器代码传到云主机上 在网上搜了很多方法介绍, 照着设置完后都无法正常连接 最后半夜尿醒来睡不着找到一篇站内文章, 提到必须注释掉一行代码 这个是其他 ...
- EF架构~充血模型设置不被持久化的属性
回到目录 在Poco实体中,一般只有属性没有方法,这在软件设计中称为贫血模型,而在DDD领域驱动设计中,比较提倡充血模型,即你的Poco实体中,即有属性,也有操作属性的方法,注意这里说的是操作属性的方 ...
- EF架构~为分组添加位运算聚合方法
回到目录 我们知道在Linq里的分组groupby可以对集合中一个或者多个字段进行分组,并对其中一个属性进行聚合,而Linq为我们提供了多种聚合方法,由aver,sum,count等,而在大叔权限体系 ...
- struts2学习笔记之十三:自定义过滤器
Struts2的拦截器 1.Struts2的拦截器只能拦截Action,拦截器是AOP的一种思路,可以使我们的系统架构 更松散(耦合度低),可以插拔,容易互换,代码不改变的情况下很容易满足客户需求 其 ...
- css 弹出层-透明层
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 如何优雅的使用vue+vux开发app -02
如何优雅的使用vue+vux开发app -02 很明显这又是一个错误的示范,请勿模仿 使用动态组件实现保留状态的路由 <!DOCTYPE html> <html> <he ...
- chrome远程调试真机上的app - 只显示空白页面
chrome远程调试真机上的app - 只显示空白页面 这个是chrome需要的插件没办法自动下载导致的,怎么办你懂得,越狱... 调试起来感觉卡顿的厉害哇,有没有更好的方式?
- 【原创】NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示
前言 NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能.这其中最流行的无非就是MINA和Netty了,MINA目前的主要版本是MINA2.而Netty的主要版本是Netty3和Netty ...
- java虚拟机内存区域的划分以及作用详解
序言 为什么有时候学着学着会突然之间觉得一切度是那么无趣,男的每个月也有那么几天难道?哈哈,不然是什么,我还是要坚持,可以做少一点,但是不能什么度不做.总会过去的,加油 --WH 一.运行时数据区 什 ...