D&F学数据结构系列——二叉堆
二叉堆(binary heap)
二叉堆数据结构是一种数组对象,它可以被视为一棵完全二叉树。同二叉查找树一样,堆也有两个性质,即结构性和堆序性。对于数组中任意位置i上的元素,其左儿子在位置2i上,右儿子在左儿子后的单元2i+1中,它的父亲在[i/2](向下取整)中。 在一个小顶堆中,对于每一个节点X,X的父亲中的关键字小于(或等于)X中的关键字,根节点除外(它没有父亲)。
因此,一个数据结构将由一个数组、一个代表最大值的整数、以及当前的堆的大小组成。一个典型的优先队列(priority queue)如下:
#ifndef _BinHeap_H
struct HeapStruct;
typedef struct HeapStruct *PriorityQueue;
PriorityQueue Initialize(int MaxElements);
void Destroy(PriorityQueue H);
void MakeEmpty(PriorityQueue H);
void Insert(ElementType X,PriorityQueue H);
ElementType DeleteMin(PriorityQueue H):
ElementType FinMin(PriorityQueue H);
int IsEmpty(PriorityQueue H);
int IsFull(PriorityQueue H);
#endif struct HeapSrtuct
{
int Capacity;
int Size;
ElementType *Elements;
};
创建一个空堆:
PriorityQueue Initialize(int MaxElements)
{
PriorityQueue H;
if(MaxElements<MinPQSize)
Error("Priority queue size is too small");
H=malloc(sizeof(struct HeapStruct));
if(H==NULL)
FatalError("Out of space!");
/*分配数组时多分配一个单位给哨兵*/
H->Elements=malloc((MaxElements+)*sizeof(ElementType));
if(H->Elements==NULL)
FatalError("Out of space!");
H->Capacity=MaxElements;
H->Size=;
H->Element[]=MinData;
return H;
}
基本的堆操作:
Insert(插入)
为将一个元素X插入到堆中,我们在下一个空闲位置创建一个空穴,否则该堆将不是完全二叉树。如果X可以放在该空穴中而并不破坏堆的序,那么插入完成。否则,我们把空穴的父节点上的元素移入该空穴中,这样,空穴就朝着根的方向上行一步。继续该过程直到X能被放入空穴中为止。这种策略叫做上滤(percolate up);
/* H->Element[0] is a sentinel */
void Insert(ElementType X,PriorityQueue H)
{
int i;
if(IsFull(H))
{
Error("priority queue is full");
return;
}
for(i=++H->Size;H->Elements[i/]>X;i/=)
H->Elements[i]=H->Elements[i/];
H->Elements[i]=X;
}
程序并没有通过“反复交换直至建立正确的序”这种方法实现上滤过程,因为一次交换需要三条赋值语句,如果一个元素上滤d层,那么由于交换而产生的赋值语句就到达3d,这里的方法只用d+1次赋值。
如果要插入的元素是新的最小值,那么它将一直被推向顶端。这样在某一时刻,i将是1,我们就需要令程序跳出while循环。当然我们可以使用明确的测试做到这一点,不过,我们采用的是把一个很小的值放到位置0处以使while循环得以终止。这个值必须小于堆中的任何值,我们称之为标记(sentinel)。这种想法类似于链表头结点的使用。通过添加一条哑信息(dummy piece of information),我们避免了每个循环都要执行一次的测试,从而节省了一些时间。
DeleteMin(删除最小元)
当删除一个最小元时,在根节点出产生了一个空穴。由于现在堆少了一个元素,因此堆中随后一个元素X必须移动到该堆的某个地方。我们将空穴的两个儿子中较小者移入空穴,这样就把空穴向下推了一层。重复该步骤直到X可以被放入空穴中。这种策略叫做下滤(percolate down)。
在上图中,删除13后,我们必须要正确地将31放到堆中。
ElementType DeleteMin(PriorityQueue H)
{
int i,Child;
ElementType MinElement,LastElement;
if(IsEmpty(H))
{
Error("Priority queue is empty");
return H->Elements[];
}
MinElement=H->Elements[];
LastElement=H->Elements[H->Size--];
for(i=;i*<=H->Size;i=Child)
{
/*找到最小的孩子*/
Child=i*;
if(Child!=H->Size&&H->Elements[Child+]<H->Elements[Child])
Child++;
/*下沉一层*/
if(LastElement>H->Elements[Child])
H->Elements[i]=H->Elements[Child];
else
break;
}
H->Elements[i]=LastElement;
return MinElement;
}
其它的堆操作:
DecreaseKey(降低关键字的值)
DecreaseKey(P,Δ,H)操作降低在位置P处的关键字的值,降值的幅度为正的量Δ。通过上滤调整堆。该操作对系统管理程序是有用的:系统管理程序能够使它们的程序以最高优先级来运行。
IncreaseKey(增加关键字的值)
IncreaseKey(P,Δ,H)操作增加在位置P处的关键字的值,增值的幅度为正的量Δ。通过下滤调整堆。许多调度程序自动地降低正在过多消耗CPU的进程的优先级。
Delete(删除)
Delete(P,H)操作删除堆中位置P上的节点。者通过首先执行DecreaseKey(P,∞,H),然后再执行DeleteMin(H)来完成。当一个进程被用户终止(而不是正常终止)时,它必须从优先队列中除去。
BuildHeap(构建堆)
BuildHeap(H)操作把N个关键字作为输入并把它们放入堆中。可以使用N个相继的Insert(插入操作来实现。平均时间是O(N)。
D&F学数据结构系列——二叉堆的更多相关文章
- 数据结构 之 二叉堆(Heap)
注:本节主要讨论最大堆(最小堆同理). 一.堆的概念 堆,又称二叉堆.同二叉查找树一样,堆也有两个性质,即结构性和堆序性. 1.结构性质: 堆是一棵被完全填满的二叉树,有可能的 ...
- 【算法与数据结构】二叉堆和优先队列 Priority Queue
优先队列的特点 普通队列遵守先进先出(FIFO)的规则,而优先队列虽然也叫队列,规则有所不同: 最大优先队列:优先级最高的元素先出队 最小优先队列:优先级最低的元素先出队 优先队列可以用下面几种数据结 ...
- D&F学数据结构系列——插入排序
插入排序(insertion sort) 插入排序由P-1趟(pass)排序组成.对于P=1趟到P=N-1趟,插入排序保证从位置0到位置P-1上的元素为已排序状态.插入排序利用了这样的事实:位置0到位 ...
- D&F学数据结构系列——二叉排序树
二叉排序树(Binary Sort Tree) 定义:对于树中的每个结点X,它的左子树中所有关键字值小于X的关键字值,而它的右子树中所有关键字值大于X的关键字值. 二叉查找树声明: #ifndef _ ...
- D&F学数据结构系列——红黑树
红黑树 定义:一棵二叉查找树如果满足下面的红黑性质,则为一棵红黑树: 1)每个结点不是红的就是黑的 2)根结点是黑的 3)每个叶结点是黑的 4)如果一个结点是红的,它的两个儿子都是黑的(即不可能有两个 ...
- D&F学数据结构系列——B树(B-树和B+树)介绍
B树 定义:一棵B树T是具有如下性质的有根树: 1)每个节点X有以下域: a)n[x],当前存储在X节点中的关键字数, b)n[x]个关键字本身,以非降序存放,因此key1[x]<=key2[x ...
- D&F学数据结构系列——前驱和后继
前驱和后继 本文所述为二叉排序树的前驱和后继,如果想了解二叉排序树的概念,可以参考我的博文http://www.cnblogs.com/sage-blog/p/3864640.html 给定一个二叉查 ...
- D&F学数据结构系列——AVL树(平衡二叉树)
AVL树(带有平衡条件的二叉查找树) 定义:一棵AVL树是其每个节点的左子树和右子树的高度最多差1的二叉查找树. 为什么要使用AVL树(即为什么要给二叉查找树增加平衡条件),已经在我之前的博文中说到过 ...
- 【数据结构与算法Python版学习笔记】树——利用二叉堆实现优先级队列
概念 队列有一个重要的变体,叫作优先级队列. 和队列一样,优先级队列从头部移除元素,不过元素的逻辑顺序是由优先级决定的. 优先级最高的元素在最前,优先级最低的元素在最后. 实现优先级队列的经典方法是使 ...
随机推荐
- C++ Vector 动态数组
Vectors 包含着一系列连续存储的元素,其行为和数组类似.访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,而查找特定值的元素所处的位置或是在Vector中插入元素则是线 ...
- Data truncated for column 错误
今天插入mysql数据数据时,报错Data truncated for column.研究了一下原理是我数据的长途超出了该字段的最大长度,所以解决办法很简单,就是修改数据库中字段属性,使其长度增加即可 ...
- ADO.NET笔记——使用Connection连接数据库,使用Command对象的ExecuteReader()方法创建DataReader对象返回多行数据
使用Connection连接数据库,使用DataReader访问数据库,并返回多行数据. 相关步骤: 需要引入两个命名空间 using System.Data; using System.Data.S ...
- JQuery 表格 隔行换色 和鼠标滑过的样式
$(document).ready(function () { $(".Pub_TB tbody tr:even td").css("background-color&q ...
- SASS语法备忘
sass语法 关于sass 3.3.0更新说明——3.3.0 sublime相关插件为:scss语法高亮,sass语法高亮,编译,保存即编译,格式化 文件后缀名 sass有两种后缀名文件:一种后缀名为 ...
- textarea 在光标处插入文字
效果演示 // 欢迎访问cssfirefly.cnblogs.com html: <textarea id="text" style="width:500px;he ...
- Session原理简述
Session存在的意义,估计每个用做web开发的人都是了解的,就为了解决HTTP是个无状态协议所带来的问题,不多说了.这里主要想说的是服务端与客户端是如何利用session进行交互的. Sessio ...
- select标签用法
<select name="type" class="textarea" onchange='bbbb(this.value)' > <opt ...
- SQL Server 2014 Always on ON Microsoft Azure New Portal(1)
以前假如需要在Azure IaaS 创建的SQL Server AlwaysOn 需要参考以下的步骤 From the MVPs: SQL Server High Availability in Wi ...
- hdu 5738 2016 Multi-University Training Contest 2 Eureka 计数问题(组合数学+STL)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5738 题意:从n(n <= 1000)个点(有重点)中选出m(m > 1)个点(选出的点只 ...