三、选择类排序

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.高级排序算法(下)的更多相关文章

  1. 数据结构和算法 – 11.高级排序算法(上)

      对现实中的排序问题,算法有七把利剑可以助你马道成功. 首先排序分为四种:       交换排序: 包括冒泡排序,快速排序.       选择排序: 包括直接选择排序,堆排序.       插入排序 ...

  2. javascript数据结构与算法--高级排序算法

    javascript数据结构与算法--高级排序算法 高级排序算法是处理大型数据集的最高效排序算法,它是处理的数据集可以达到上百万个元素,而不仅仅是几百个或者几千个.现在我们来学习下2种高级排序算法-- ...

  3. javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法)

    javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法) 一.快速排序算法 /* * 这个函数首先检查数组的长度是否为0.如果是,那么这个数组就不需要任何排序,函数直接返回. * ...

  4. javascript高级排序算法之快速排序(快排)

    javascript高级排序算法之快速排序(快排)我们之前讨论了javascript基本排序算法 冒泡排序 选择排序 插入排序 简单复习: 冒泡排序: 比较相邻的两个元素,如果前一个比后一个大,则交换 ...

  5. 【高级排序算法】1、归并排序法 - Merge Sort

    归并排序法 - Merge Sort 文章目录 归并排序法 - Merge Sort nlogn 比 n^2 快多少? 归并排序设计思想 时间.空间复杂度 归并排序图解 归并排序描述 归并排序小结 参 ...

  6. 【高级排序算法】2、归并排序法的实现-Merge Sort

    简单记录 - bobo老师的玩转算法系列–玩转算法 -高级排序算法 Merge Sort 归并排序 Java实现归并排序 SortTestHelper 排序测试辅助类 package algo; im ...

  7. 插入排序算法--直接插入算法,折半排序算法,希尔排序算法(C#实现)

    插入排序算法主要分为:直接插入算法,折半排序算法(二分插入算法),希尔排序算法,后两种是直接插入算法的改良.因此直接插入算法是基础,这里先进行直接插入算法的分析与编码. 直接插入算法的排序思想:假设有 ...

  8. 数据结构与算法之--高级排序:shell排序和快速排序

    高级排序比简单排序要快的多,简单排序的时间复杂度是O(N^2),希尔(shell)排序大约是O(N*(logN)^2),而快速排序是O(N*logN). 说明:下面以int数组的从小到大排序为例. 希 ...

  9. 数据结构和算法 – 12.高级查找算法(下)

    哈希(散列)技术既是一种存储方法,也是一种查找方法.然而它与线性表.树.图等结构不同的是,前面几种结构,数据元素之间都存在某种逻辑关系,可以用连线图示表示出来,而哈希技术的记录之间不存在什么逻辑关系, ...

随机推荐

  1. Xcode 6制作动态及静态Framework和各种坑

    Xcode 6制作动态及静态Framework http://www.cocoachina.com/ios/20141126/10322.html 有没有写SDK或者要将一些常用的工具类做成Frame ...

  2. (转)一个JavaWeb项目开发总结

    原文地址:http://www.cnblogs.com/lzb1096101803/p/4907775.html 一.学会如何读一个JavaWeb项目源代码 步骤:表结构->web.xml-&g ...

  3. Hello,World

    引用自http://www.cnblogs.com/jbelial/archive/2013/05/08/3067471.html#2676127 题目: 1 public class text { ...

  4. OI总结(垃圾排版就忽略了吧)

    学OI一年了,到现在联赛所需要的知识已经基本学完了.现在,有必要回过头来,总结总结自己一年来学到的知识以及得到的经验教训. 基础 语言基础 C++的语言基础啥的就略了吧. 算法复杂度分析 O:复杂度的 ...

  5. ubuntu 14.04 对exfat的支持

    sudo apt-get install exfat-utils exfat-fuse sudo reboot

  6. phpcms--模型管理,推荐位管理,类别管理

    phpcms的默认设置不一定能满足需求,这个时候必须启用[模型管理],[推荐位管理],[类别管理]三个高级功能 为什么需要使用这些功能呢,因为后台添加内容的时候需要不同的模型 而模型通过什么来展现呢, ...

  7. mkdir:批量创建文件夹

    问题:mkdir dir[0-9]创建文件夹时,并没有如预期创建dir0~dir9这几个文件夹,而是创建了dir[0-9]这一个文件夹. 网上看了些相关资料,发现以前对[0-9]的理解不够透彻: &q ...

  8. C# 毕业证书打印《三》

    打印很关键的方法,打印方法DataPrint(),将你要打印的数据信息发送到打印机就可以了,打印机将自动处理. public void DataPrint() { try { PrintDocumen ...

  9. jQuery之元素筛选

      1.eq()  筛选指定索引号的元素2.first() 筛选出第一个匹配的元素3.last() 筛选出最后一个匹配的元素4.hasClass() 检查匹配的元素是否含有指定的类5.filter() ...

  10. poj 1125 (floyd)

    http://poj.org/problem?id=1125. 题意:在经纪人的圈子里,他们各自都有自己的消息来源,并且也只相信自己的消息来源,他们之间的信息传输也需要一定的时间.现在有一个消息需要传 ...