数据结构——堆
来源:互联网 发布:测试常用的linux命令 编辑:程序博客网 时间:2024/05/01 00:04
转载自数据结构——堆
==================================================================================================================================
原文题目:Heap Data Structure
By Arman S. | 7 Mar 2007
原文链接:点这里
简介
本文简要介绍数据结构 堆 的概念并提供了实现源码: CHeapTree类。CHeapTree类的实现是基于一个自动增长的数组。
什么是堆
堆是一种特殊的二叉完全树。堆的一个主要特点是它以一定的偏序(a partial order)来保存所有节点[译者注:此处的偏序是指不完全的排序,堆只需要满足父节点大于两个子节点,而子节点之间没有要求]。作为一颗完全树,一层中的节点是从左到右填满的。如果一个节点没有左儿子,那么它一定没有右儿子。并且在第h层中如果存在节点,那么第h-1层必须是填满的。
以下是堆的正式定义(摘自Computer Algorithms by S. Baase and A. Van Gelder):
一个二叉树V是一个堆,当且仅当它满足以下条件:
- V从根节点至h-1层是完全树
- 所有的叶子节点只存在于h与h-1层上
- 所有到达h层叶子节点的路劲都在到达h-1层叶子节点路径的左侧
堆有两种:最大堆和最小堆。最小堆中每个节点的优先级小于或者等于它的子节点;最大堆则相反,每个节点的优先级都大于或者等于它的子节点。
图示最大堆(左)和最小堆(右):
实现细节
CHeapTree类通过一个数组,从上至下、从左至右地保存树中的节点来实现堆。因此,上述图示中的最大堆就可以表示为10,9,8,6,1,5。在这种表示方式中,第j个节点的子节点和父节点的表达如下(假设起始索引值是0):
- 左子节点 = j*2-1
- 右子节点 = j*2 = 左子节点+1
- 父节点 = (j-1)/ 2
如果索引值越界,则该节点不存在。
代价
建堆过程中的比较次数:O(n)
删除堆的比较次数:2*n*lg(n)[译者注:删除一个元素的比较次数为2*lg[n],所以要删除所有元素需要n*2*lg(n)]
堆排序的平均时间复杂度是n*lg(n)
template <class TID, class TDATA>class CHeapTree{ struct _NODE { TID id; TDATA data; }; _NODE *m_data;public: CHeapTree(int nInitMax = 100); ~CHeapTree(); bool IsEmpty() const { return m_nSize == 0; } int GetSize() const { return m_nSize; } void Insert(const TID &id, const TDATA &data); bool RemoveTop(); bool RemoveAll(); bool GetTopID(TID *pid) const; bool GetTopData(TDATA *pdata) const; bool GetData(const TID &id, TDATA *pdata) const; bool ResetData(const TID &id, const TDATA &data);private: void _ReformatHeap(int iRoot);};
CHeapTree类实现了堆的基本操作。每个节点中排序基准的数据类型是TDATA类型。所以,如果TDATA是一种用户自定义的数据类型,需要实现<,=,>的运算符重载,即该类型的比较逻辑需由用户给出。TID是用来唯一表示一个节点的值。
默认情况下,CHeapTree是一个最小堆即TDATA中最小值具有最高的排序优先权。如果需要一个最大堆,将TDATA类型的比较运算符的逻辑倒置即可。
如何使用
使用该CHeapTree类很简单,可以如下所示:
// int=id, float=priority [as less as better]CHeapTree<int, float> h;h.Insert(0, 0.1f);h.Insert(1, 0.2f);h.Insert(2, 0.15f);h.Insert(3, 0.3f);h.Insert(4, 0.21f);h.ResetData(3, 0.19f);// The order should be [0, 2, 3, 1, 4]while (!h.IsEmpty()) { int top; h.GetTopID(&top); float data; h.GetTopData(&data); cout << "(" << top << " : " << data << ")/n"; h.RemoveTop();}
- 数据结构——堆
- 数据结构——堆
- 数据结构——堆
- 数据结构——堆
- 数据结构——堆
- 数据结构——堆
- 数据结构——堆
- 数据结构——堆
- 堆—数据结构
- 数据结构 — 堆排序
- 数据结构—堆
- 数据结构—堆
- 数据结构——堆排序
- 数据结构——堆排序
- 数据结构学习——堆
- 数据结构——堆排序
- 数据结构专题——堆
- 数据结构系列——堆
- SecureCRT异常关闭,后台进程中断原因及解决办法---nohup
- 记单词工具拓展引起的选中即复制想法
- 笔试真题解析 TT 研发工程师笔试卷
- UIKit 力学教程
- Hive 1.1.1 启动错误
- 数据结构——堆
- Theme Section(KMP应用 HDU4763)
- 嵌入式linux程序之调试方法
- 常用数据类型对应字节数
- HDU 1113 Word Amalgamation -- 字符串处理+排序
- 剑指offer:顺时针打印矩阵
- C++中的虚基类
- 软肋
- 正则表达式