数据结构和算法 – 11.高级排序算法(下)
三、选择类排序
3.1.简单选择排序
http://www.cnblogs.com/tangge/p/5338734.html#XuanZe
3.2 堆排序
要知道堆排序,首先要了解一下二叉树的模型。
下图就是一颗二叉树

那么堆排序中有两种情况(看上图理解):
大根堆: 就是说父节点要比左右孩子都要大。
小根堆: 就是说父节点要比左右孩子都要小。
那么要实现堆排序,必须要做两件事情:
第一:构建大根堆。

首先这是一个无序的堆,那么我们怎样才能构建大根堆呢?
第一步: 首先我们发现,这个堆中有2个父节点(2,3);
第二步: 比较2这个父节点的两个孩子(4,5),发现5大。
第三步: 然后将较大的右孩子(5)跟父节点(2)进行交换,至此3的左孩子堆构建完毕,

第四步: 比较第二个父节点(3)下面的左右孩子(5,1),发现左孩子5大。
第五步: 然后父节点(3)与左孩子(5)进行交换,注意,交换后,堆可能会遭到破坏,
必须按照以上的步骤一,步骤二,步骤三进行重新构造堆。
最后构造:

第二:输出大根堆。
至此,我们把大根堆构造出来了,那怎么输出呢?我们做大根堆的目的就是要找出最大值,
那么我们将堆顶(5)与堆尾(2)进行交换,然后将(5)剔除根堆,由于堆顶现在是(2),
所以破坏了根堆,必须重新构造,构造完之后又会出现最大值,再次交换和剔除,最后也就是俺们
要的效果了。
///<summary>
/// 构建堆
///</summary>
///<param name="list">待排序的集合</param>
///<param name="parent">父节点</param>
///<param name="length">输出根堆时剔除最大值使用</param>
public static void HeapAdjust(List<int> list, int parent, int length)
{
//temp保存当前父节点
int temp = list[parent]; //得到左孩子(这可是二叉树的定义哇)
int child = 2 * parent + 1; while (child < length)
{
//如果parent有右孩子,则要判断左孩子是否小于右孩子
if (child + 1 < length && list[child] < list[child + 1])
child++; //父节点大于子节点,不用做交换
if (temp >= list[child])
break; //将较大子节点的值赋给父亲节点
list[parent] = list[child]; //然后将子节点做为父亲节点,已防止是否破坏根堆时重新构造
parent = child; //找到该父节点左孩子节点
child = 2 * parent + 1;
}
//最后将temp值赋给较大的子节点,以形成两值交换
list[parent] = temp;
} ///<summary>
/// 堆排序
///</summary>
///<param name="list">待排序的集合</param>
///<param name="top">前K大</param>
///<returns></returns>
public List<int> HeapSort(List<int> list, int top)
{
//string joinlist = string.Join(",", list.ToList());
List<int> topNode = new List<int>(); //list.Count/2-1:就是堆中非叶子节点的个数
for (int i = list.Count / 2 - 1; i >= 0; i--)
{
HeapAdjust(list, i, list.Count);
//joinlist = string.Join(",", list.ToList());
} //最后输出堆元素(求前K大)
for (int i = list.Count - 1; i >= list.Count - top; i--)
{
//堆顶与当前堆的第i个元素进行值对调
int temp = list[0];
list[0] = list[i];
list[i] = temp;
//joinlist = string.Join(",", list.ToList());
//最大值加入集合
topNode.Add(temp); //因为顺序被打乱,必须重新构造堆
HeapAdjust(list, 0, i);
//joinlist = string.Join(",", list.ToList());
}
return topNode;
}
List<int> list1 = new List<int>();
int[] array1 = new int[] { 20, 40, 50, 10, 60 };
list1.AddRange(array1);
new QuickSortClass().HeapSort(list1, 5); Console.WriteLine("堆排序:");
Console.Write(string.Join(",", list1.ToList()));


总结:堆排序的执行时间主要由建立初始堆和反复调整堆这两个部分的时间开销组成,由于堆排序对原始记录的排序状态并不敏感,因此它无论是最好、最坏和平均时间复杂度均为O(nlog2n)。这在性能上显然要远远好过于冒泡、简单选择、直接插入的O(n2)的时间复杂度了。另外,由于初始构建堆所需的比较次数较多,因此,它并不适合待排序序列个数较少的情况。
四、归并类排序
4.1 二路归并排序介绍
4.2 二路归并排序实现

总结:
(1)当待排序序列的记录数n较小的时候(一般n<=50),可以采用直接插入排序、直接选择排序或冒泡排序:
若序列初始状态基本为正序,则应选用直接插入排序、冒泡排序。
如果单条记录本身信息量较大,由于直接插入排序所需的记录移动操作较直接选择排序多,因此用直接选择排序较好。
(2)当待排序序列的记录数n较大的时候,则应采用时间复杂度为O(nlog2n)的排序方法,如:快速排序、堆排序或归并排序。
快速排序时目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字随机分布时,快速排序的平均时间最短,.NET中集合类的内置排序方法(例如:Array.Sort())也是使用了快速排序实现的。
堆排序需要的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况O(n2)。
归并排序需要大量的辅助空间,因此不值得提倡使用,但是如果要将两个有序序列组合成一个新的有序序列,最好的方法就是归并排序。
数据结构和算法 – 11.高级排序算法(下)的更多相关文章
- 数据结构和算法 – 11.高级排序算法(上)
对现实中的排序问题,算法有七把利剑可以助你马道成功. 首先排序分为四种: 交换排序: 包括冒泡排序,快速排序. 选择排序: 包括直接选择排序,堆排序. 插入排序 ...
- javascript数据结构与算法--高级排序算法
javascript数据结构与算法--高级排序算法 高级排序算法是处理大型数据集的最高效排序算法,它是处理的数据集可以达到上百万个元素,而不仅仅是几百个或者几千个.现在我们来学习下2种高级排序算法-- ...
- javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法)
javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法) 一.快速排序算法 /* * 这个函数首先检查数组的长度是否为0.如果是,那么这个数组就不需要任何排序,函数直接返回. * ...
- javascript高级排序算法之快速排序(快排)
javascript高级排序算法之快速排序(快排)我们之前讨论了javascript基本排序算法 冒泡排序 选择排序 插入排序 简单复习: 冒泡排序: 比较相邻的两个元素,如果前一个比后一个大,则交换 ...
- 【高级排序算法】1、归并排序法 - Merge Sort
归并排序法 - Merge Sort 文章目录 归并排序法 - Merge Sort nlogn 比 n^2 快多少? 归并排序设计思想 时间.空间复杂度 归并排序图解 归并排序描述 归并排序小结 参 ...
- 【高级排序算法】2、归并排序法的实现-Merge Sort
简单记录 - bobo老师的玩转算法系列–玩转算法 -高级排序算法 Merge Sort 归并排序 Java实现归并排序 SortTestHelper 排序测试辅助类 package algo; im ...
- 插入排序算法--直接插入算法,折半排序算法,希尔排序算法(C#实现)
插入排序算法主要分为:直接插入算法,折半排序算法(二分插入算法),希尔排序算法,后两种是直接插入算法的改良.因此直接插入算法是基础,这里先进行直接插入算法的分析与编码. 直接插入算法的排序思想:假设有 ...
- 数据结构与算法之--高级排序:shell排序和快速排序
高级排序比简单排序要快的多,简单排序的时间复杂度是O(N^2),希尔(shell)排序大约是O(N*(logN)^2),而快速排序是O(N*logN). 说明:下面以int数组的从小到大排序为例. 希 ...
- 数据结构和算法 – 12.高级查找算法(下)
哈希(散列)技术既是一种存储方法,也是一种查找方法.然而它与线性表.树.图等结构不同的是,前面几种结构,数据元素之间都存在某种逻辑关系,可以用连线图示表示出来,而哈希技术的记录之间不存在什么逻辑关系, ...
随机推荐
- css设置input中placeholder字体
设置input中placeholder字体颜色 input::-webkit-input-placeholder {color:@a;} input:-moz-placeholder {color:@ ...
- Mysql报错Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist
安装mysql后,启动时候没有启动成功,查看了下日志报错如下:---------------------------------------------1 可以:初始化mysql:mysql_in ...
- 国外开源的PACS服务器
国外开源的PACS服务器 罗朝辉(http://www.cnblogs.com/kesalin/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 名称:Dcm4che评级:★ ...
- 23 使用环境 UsageEnvironment——Live555源码阅读
23 使用环境 UsageEnvironment——Live555源码阅读(三)UsageEnvironment 23 使用环境 UsageEnvironment——Live555源码阅读(三)Usa ...
- Python之函数之路
1 集合 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 创建集合 a = {3, 5, 9, 9, ...
- Maven 实用命令和技巧
1.Jar冲突排查 maven dependency:tree 人工排除
- Appium+Robotframework实现Android应用的自动化测试-4:AppiumLibrary介绍和安装
Appium是个好东东,Android,iOS都支持,并且居然RobotFramework也支持Appium了,这就是本文要介绍的AppiumLibrary. 通过前面的文章大家知道可以使用多种语言来 ...
- ios 转发一篇对于6 plus的分辨率模式的说明
http://segmentfault.com/q/1010000002545515 分为兼容模式和高分辨率模式. 兼容模式 当你的 app 没有提供 3x 的 LaunchImage 时,系统默认进 ...
- Java for LeetCode 229 Majority Element II
Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorit ...
- JSP页面格式化货币金额,千分位
<fmt:formatNumber value="${值}" pattern="currency"></fmt:formatNumber> ...