D&F学数据结构系列——二叉堆

二叉堆(binary heap)

二叉堆数据结构是一种数组对象,它可以被视为一棵完全二叉树。同二叉查找树一样,堆也有两个性质,即结构性和堆序性。对于数组中任意位置i上的元素,其左儿子在位置2i上,右儿子在左儿子后的单元2i+1中,它的父亲在[i/2](向下取整)中。

因此,一个数据结构将由一个数组、一个代表最大值的整数、以及当前的堆的大小组成。一个典型的优先队列(priority queue)如下:

 1 #ifndef _BinHeap_H
 2 struct HeapStruct;
 3 typedef struct HeapStruct *PriorityQueue;
 4 PriorityQueue Initialize(int MaxElements);
 5 void Destroy(PriorityQueue H);
 6 void MakeEmpty(PriorityQueue H);
 7 void Insert(ElementType X,PriorityQueue H);
 8 ElementType DeleteMin(PriorityQueue H):
 9 ElementType FinMin(PriorityQueue H);
10 int IsEmpty(PriorityQueue H);
11 int IsFull(PriorityQueue H);
12 #endif
13
14 struct HeapSrtuct
15 {
16    int Capacity;
17    int Size;
18    ElementType *Elements;
19 };

创建一个空堆:

 1 PriorityQueue Initialize(int MaxElements)
 2 {
 3    PriorityQueue H;
 4    if(MaxElements<MinPQSize)
 5      Error("Priority queue size is too small");
 6    H=malloc(sizeof(struct HeapStruct));
 7    if(H==NULL)
 8      FatalError("Out of space!");
 9    /*分配数组时多分配一个单位给哨兵*/
10    H->Elements=malloc((MaxElements+1)*sizeof(ElementType));
11    if(H->Elements==NULL)
12      FatalError("Out of space!");
13    H->Capacity=MaxElements;
14    H->Size=0;
15    H->Element[0]=MinData;
16    return H;
17 }

基本的堆操作:

Insert(插入)

为将一个元素X插入到堆中,我们在下一个空闲位置创建一个空穴,否则该堆将不是完全二叉树。如果X可以放在该空穴中而并不破坏堆的序,那么插入完成。否则,我们把空穴的父节点上的元素移入该空穴中,这样,空穴就朝着根的方向上行一步。继续该过程直到X能被放入空穴中为止。这种策略叫做上滤(percolate up);

 1 /* H->Element[0] is a sentinel */
 2 void Insert(ElementType X,PriorityQueue H)
 3 {
 4    int i;
 5    if(IsFull(H))
 6    {
 7      Error("priority queue is full");
 8      return;
 9     }
10      for(i=++H->Size;H->Elements[i/2]>X;i/=2)
11        H->Elements[i]=H->Elements[i/2];
12      H->Elements[i]=X;
13 }

程序并没有通过“反复交换直至建立正确的序”这种方法实现上滤过程,因为一次交换需要三条赋值语句,如果一个元素上滤d层,那么由于交换而产生的赋值语句就到达3d,这里的方法只用d+1次赋值。

如果要插入的元素是新的最小值,那么它将一直被推向顶端。这样在某一时刻,i将是1,我们就需要令程序跳出while循环。当然我们可以使用明确的测试做到这一点,不过,我们采用的是把一个很小的值放到位置0处以使while循环得以终止。这个值必须小于堆中的任何值,我们称之为标记(sentinel)。这种想法类似于链表头结点的使用。通过添加一条哑信息(dummy piece of information),我们避免了每个循环都要执行一次的测试,从而节省了一些时间。

D&F学数据结构系列——二叉堆

时间: 2024-12-27 23:54:38

D&F学数据结构系列——二叉堆的相关文章

D&amp;F学数据结构系列——红黑树

红黑树 定义:一棵二叉查找树如果满足下面的红黑性质,则为一棵红黑树: 1)每个结点不是红的就是黑的 2)根结点是黑的 3)每个叶结点是黑的 4)如果一个结点是红的,它的两个儿子都是黑的(即不可能有两个连续的红色结点) 5)对于每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点 性质: 这些约束确保了红黑树的关键特性: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长.结果是这个树大致上是平衡的.因为操作比如插入.删除和查找某个值的最坏情况时间都要求与树的高度成比例,这个在高度上

D&amp;F学数据结构系列——前驱和后继

前驱和后继 本文所述为二叉排序树的前驱和后继,如果想了解二叉排序树的概念,可以参考我的博文*** 给定一个二叉查找树中的结点,有时候要求找出在中序遍历顺序下它的后继.如果所有的关键字均不同,则某一结X点的后继就是所有(结点值)大于X的结点中最小的那个. 包含两种情况: 情况一:结点X的右子树非空,则X的后继是其右子树中最左的结点 情况二:结点X的右子树为空,设X的后继为Y.则Y是X的最低祖先结点,且Y的左儿子也是X的祖先(X自身也可以看做是X的祖先) 1 BT* TreeSuccessor(BT

D&amp;F学数据结构系列——B树(B-树和B+树)介绍

B树 定义:一棵B树T是具有如下性质的有根树: 1)每个节点X有以下域: a)n[x],当前存储在X节点中的关键字数, b)n[x]个关键字本身,以非降序存放,因此key1[x]<=key2[x]<=...<=keyn[x][x], c)leaf[x],是一个布尔值,如果x是叶子的话,则它为TRUE,如果x为一个内节点,则为FALSE. 2)每个内节点包含n[x]+1个指向其子女的指针c1[x],c2[x],...,cn[x]+1[x].叶节点没有子女,故它们的ci域无意义. 3)各关键

【数据结构】二叉堆

看到一篇很好的博文,来自http://blog.csdn.net/morewindows/article/details/6709644 下面是博文内容 堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先讲解下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆).

数据结构 之 二叉堆(Heap)

注:本节主要讨论最大堆(最小堆同理). 一.堆的概念 堆,又称二叉堆.同二叉查找树一样,堆也有两个性质,即结构性和堆序性. 1.结构性质: 堆是一棵被全然填满的二叉树.有可能的例外是在底层.底层上的元素从左到右填入.这种树称为全然二叉树(complete binary tree).下图就是这样一个样例. 对于全然二叉树,有这样一些性质: (1).一棵高h的全然二叉树,其包括2^h ~ (2^(h+1) - 1)个节点.也就是说.全然二叉树的高是[logN],显然它是O(logN). (2).全然

数据结构之二叉堆、堆排序

前言 上一篇写了数据结构之二叉搜索树.AVL自平衡树,这次来写堆. 堆的创造者 很久以前排序算法的时间复杂度一直是O(n^2), 当时学术界充斥着"排序算法不可能突破O(n^2)"的声音,直到1959年,由D.L.Shell提出了一种排序算法,希尔排序(Shell Sort),才打破了这种不可能的声音,把排序算法的时间复杂度提升到了O(n^3/2)! 当科学家们知道这种"不可能"被突破之后,又相继有了更快的排序算法,"不可能超越O(n^2)"彻底

优先队列 - 数据结构 (二叉堆)

优先队列包括二叉堆.d-堆.左式堆.斜堆.二项队列等 1.二叉堆 堆是一棵被完全填满的二叉树,有可能例外的是在底层,底层上的元素从左到右填入.这样的树称为完全二叉树. 堆序的性质:在一个堆中,对于每一个节点X,X的父亲的关键字小于(或等于)X中的关键字,根节点除外(它没有父节点).完全二叉树可以用数组实现. //关于二叉堆的头文件定义 如果要插入的元素是新的最小值,那么它将一直被推向堆顶.这样在某一个时刻,i将是1,我们就需要另Insert函数令程序跳出while循环,这个值必须保证小于或者至少

数据结构学习——二叉堆ADT(程序化)

参考书籍<数据结构与算法分析--C语言描述> 关于堆的一些基本概念,可参见小zz的另一篇博文. /*本例程实现的是最小堆,最大堆类似*/ #include<stdio.h> #include<stdlib.h> #include<stdbool.h> #include<string.h> #define MAX 13 typedef struct BHeap { int Capacity;//堆的最大容量 int Size;//当前堆大小 int

数据结构之二叉堆(构建堆,堆排序)-(七)

/* * @author Lip * @date 2015-04-23 */ public class Heap { public static void main(String[] args) { // TODO Auto-generated method stub //System.out.println((int)-1.5); int []array={4,2,7,9,3,6,1,12,10,5}; System.out.println("原始:"); printHeapByLe