基于比较的算法之五:堆排序

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
通常堆是通过一维数组来实现的。在起始数组为 0
的情形中:
父节点i的左子节点在位置
(2*i+1);

父节点i的右子节点在位置
(2*i+2);

子节点i的父节点在位置
floor((i-1)/2);

在堆的数据结构中,堆中的最大值总是位于根节点。堆中定义以下几种操作:
最大堆调整(maxHeapify):将堆的末端子节点作调整,使得子节点永远小于父节点

创建最大堆(buildMaxHeap):将堆所有数据重新排序

堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算

现在给出C#实现的堆排序:


 1  public class HeapSort<T> : ISort<T> where T : IComparable<T>
2 {
3 public void Sort(T[] array, int startIndex, int endIndex)
4 {
5 //Heapify the array
6 buildMaxHeap(array, startIndex, endIndex);
7 //Sort from endIndex to (startIndex-1),
8 //when i=startIndex, then only one node left,then no any requirement to heapify it.
9 for (int i = endIndex; i > startIndex; i--)
10 {
11 //swap array[i] and array[startIndex]
12 T tmpT = array[i];
13 array[i] = array[startIndex];
14 array[startIndex] = tmpT;
15 maxHeapify(array, startIndex, i - 1, startIndex);
16 }
17 }
18 private void buildMaxHeap(T[] array, int startIndex, int endIndex)
19 {
20 //Leaf node is from (endIndex-startIndex+1)/2+1+startIndex to endIndex
21 // //O(n*Log(n))
22 for (int i = (endIndex - startIndex + 1) / 2 + startIndex; i >= startIndex; i--)
23 {
24 //O(Log(n))
25 maxHeapify(array, startIndex, endIndex, i);
26 }
27 }
28
29 //insert a new root node for two child maxHeap.
30 private void maxHeapify(T[] array, int startIndex, int endIndex, int newRootIndex)
31 {
32
33 //int L = (newRootIndex - startIndex) * 2 + 1 + startIndex;
34 int L = (newRootIndex - startIndex + 1) * 2 + startIndex - 1;//The array base is from 0.
35 int R = L + 1;
36 int tmpLargestIndex = newRootIndex;
37 if (L <= endIndex && array[L].CompareTo(array[tmpLargestIndex]) > 0)
38 {
39 tmpLargestIndex = L;
40 }
41 if (R <= endIndex && array[R].CompareTo(array[tmpLargestIndex]) > 0)
42 {
43 tmpLargestIndex = R;
44 }
45 if (tmpLargestIndex != newRootIndex)
46 {
47 //swap array[tmpLargestIndex] and array[newRootIndex]
48 T tmpT = array[tmpLargestIndex];
49 array[tmpLargestIndex] = array[newRootIndex];
50 array[newRootIndex] = tmpT;
51 //MaxHeapify the child branch, the newRootIndex= tmpLargestIndex
52 maxHeapify(array, startIndex, endIndex, tmpLargestIndex);
53 }
54 }
55 }

作者:Andy Zeng

欢迎任何形式的转载,但请务必注明出处。

http://www.cnblogs.com/andyzeng/p/3699195.html

基于比较的算法之五:堆排序,码迷,mamicode.com

时间: 2024-10-24 11:07:06

基于比较的算法之五:堆排序的相关文章

排序算法系列——堆排序

记录学习点滴,菜鸟成长记 堆排序引入了另一种算法设计技巧:使用一种我们称之为“堆”的数据结构来进行数据管理. 堆排序算是真正意义上的利用数据结构来求解数组排序的方法. “插入排序”和“归并排序”可以看做是一种“计算机体力活”,体现的思想更多的是去模拟最简单的人类思维,比如插入排序过程中的比较,归并中子问题合并时的比较. “堆排序”可以看做是“计算机脑力活”,他利用了一种结构化的语言来表达,这种结构化带来一些性质,比如左右孩子.比[堆大小的一半向下取整]大的下标都是叶节点不需要维护其最大堆性质等.

QT:用QSet储存自定义结构体的问题——QSet和STL的set是有本质区别的,QSet是基于哈希算法的,要求提供自定义==和qHash函数

前几天要用QSet作为储存一个自定义的结构体(就像下面这个程序一样),结果死活不成功... 后来还跑到论坛上问人了,丢脸丢大了... 事先说明:以下这个例子是错误的 [cpp] view plaincopyprint? #include <QtCore> struct node { int cx, cy; bool operator < (const node &b) const { return cx < b.cx; } }; int main(int argc, cha

基于朴素贝叶斯分类算法的邮件过滤系统

转自穆晨 阅读目录 前言 准备数据:切分文本 训练并测试 小结 回到顶部 前言 朴素贝叶斯算法最为广泛而经典的应用毫无疑问是文档分类,更具体的情形是邮件过滤系统. 本文详细地讲解一个基于朴素贝叶斯分类算法的邮件过滤系统的具体实现. 本文侧重于工程实现,至于其中很多算法的细节请参考之前的一篇文章:朴素贝叶斯分类算法原理分析与代码实现. 回到顶部 准备数据:切分文本 获取到文本文件之后,首先要做的是两件事情: 1. 将文本文件转换为词汇列表 2. 将上一步的结果进一步转换为词向量 对于 1,具体来说

第六篇:基于朴素贝叶斯分类算法的邮件过滤系统

前言 朴素贝叶斯算法最为广泛而经典的应用毫无疑问是文档分类,更具体的情形是邮件过滤系统. 本文详细地讲解一个基于朴素贝叶斯分类算法的邮件过滤系统的具体实现. 本文侧重于工程实现,至于其中很多算法的细节请参考之前的一篇文章:朴素贝叶斯分类算法原理分析与代码实现. 准备数据:切分文本 获取到文本文件之后,首先要做的是两件事情: 1. 将文本文件转换为词汇列表 2. 将上一步的结果进一步转换为词向量 对于 1,具体来说,就是将文本文件以非字母或数字之外的字符为界进行切割. 仅仅使用字符串的 split

图像检索:基于形状特征的算法

本文节选自<基于形状特征的图像检索算法研究> 基于形状特征的图像检索算法相对于颜色特征和纹理特征来说,使用的稍微少一些.摘录了其中的几种算法,不做深入剖析了. 形状通常与图像中的特定目标对象有关,是人们的视觉系统对目标的最初认识,有一定的语义信息,被认为是比颜色特征和纹理特征更高一层的特征.形状描述的准确与否是决定图像检索算法优劣的重要因素,一个好的形状描述符应具备独特性.完备性.几何不变性.灵活性以及抽象性.形状的描述符大体可以分为两大类:第一类是描述形状目标区域边界轮廓的像素集合,称为基于

【数据结构与算法】堆排序

堆排序的时间复杂度是O(nlogn),下面上代码 public class HeapSort { public void adjustHeap(int[] in, int index, int length) { int leftcIndex = index * 2 + 1; int rightcIndex = index * 2 + 2; int bigest = index; while (leftcIndex < length || rightcIndex < length) { if

最短路径算法之五——邻接表

邻接表 邻接矩阵来存储图的信息相对于非完全图,会浪费大量的空间,同时在求最短路径的时候也会有多余的计算浪费时间. 使用邻接表可以节约这些浪费的时间. 这里介绍的是用数组模拟的邻接表: 定义begin[MAXN],end[MAXN],dis[MAXN],first[MAXN],next[MAXN]五个数组. 例子描述如下: 4 5 1 4 9 4 3 8 1 2 5 2 4 6 1 3 7 Step1: 1 2 3 4 5 begin end dis first -1 -1 -1 -1 -1 ne

【常用算法】KDTree,局部敏感哈希LSH,在基于最近邻的算法中,当N特别大的时候(TODO)

基于最近邻的算法,在各种情况下经常使用, 比如10万个用户,对每一个用户分别查找最相似的用户, 当N特别大的时候,效率就不是很高,比如当N=10^5,时已经不太好算了,因为暴力法时间复杂度为O(N^2). 故需要特殊的手段,这里有两个常用的方法, 一个是KDT树(还有Ball Tree),一个是局部敏感哈希(近似算法,得到得是满足一定置信区间的结果) KDT: O(N*longN) 局部敏感哈希(LSH):跟桶大小有关 1#  K-Dimensional Tree,KDT, https://en

【Vj作业】【拓扑排序经典理解题】Ordering Tasks 1、Kahn算法;2、基于DFS的算法。

2018-02-13 链接   https://cn.vjudge.net/contest/211129#problem/D John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task is only possible if other tasks have already been executed.InputThe input will consist o