二叉堆
2013-10-11 20:45
232 查看
堆是一棵被完全填满的二叉树,有可能的例外是在底层。
因为完全二叉树很有规律,因此可以用数组来表示,而不需要用指针。对于数组中任一位置i上的元素,其左儿子在2i上,右儿子在左儿子后的单元中。它的父亲则在i/2中。因此,遍历该树所需要的操作也非常简单,唯一的问题是最大的堆大小需要事先估计。
因此,一个堆数据结构由一个数组(不论是什么类型)、一个代表最大值的整数以及当前堆的大小组成。
堆快速执行的性质是堆序性。在一个堆中,对于每一个节点X ,X 的父亲中的关键字小于或等于X 中的关键字,根节点除外。(相应的,也可以大于或等于)
1:声明
2:初始化
3:插入
为将一个元素X 插入到堆中,在下一个空闲位置即最后一个元素创建一个空位置(添加了一个新元素)。否则该堆就不是完全堆了。如果X 可以放在这个位置又不破坏堆的性质,那么插入完成,否则,就将把它的父节点的元素移入该空穴,这样,空穴就向上移了一层。直到符合堆的性质。
也可以先将X放入空穴,然后与父节点比较,不符合的话就交换,但是这样时间较慢。
如果插入的数时新的最小值,那么将一直上升到顶端,i=1,那么需要跳出for循环,令位置0处的值足够小就可以了,称之为标记。
4:DeleteMin
当删除一个最小元时,在根节点处产生了一个空穴,需要将最后一个元素正确的移入空穴。将空穴的两个儿子中的较小者放入空穴中,重复该步骤直到可以将堆中最后一个元素放入空穴中。
因为完全二叉树很有规律,因此可以用数组来表示,而不需要用指针。对于数组中任一位置i上的元素,其左儿子在2i上,右儿子在左儿子后的单元中。它的父亲则在i/2中。因此,遍历该树所需要的操作也非常简单,唯一的问题是最大的堆大小需要事先估计。
因此,一个堆数据结构由一个数组(不论是什么类型)、一个代表最大值的整数以及当前堆的大小组成。
堆快速执行的性质是堆序性。在一个堆中,对于每一个节点X ,X 的父亲中的关键字小于或等于X 中的关键字,根节点除外。(相应的,也可以大于或等于)
1:声明
#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 FindMin( PriorityQueue H ); int IsEmpty( PriorityQueue H ); int IsFull( PriorityQueue H ); #endif struct HeapStruct { int Capacity; int Size; ElementType *Elements; };
2:初始化
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 + 1 ) * sizeof( ElementType ) ); if( H->Elements == NULL ) FatalError( "Out of space" ); H->Capacity = MaxElements; H->Size = 0; H->Elements[0] =MinData; return H; }
3:插入
为将一个元素X 插入到堆中,在下一个空闲位置即最后一个元素创建一个空位置(添加了一个新元素)。否则该堆就不是完全堆了。如果X 可以放在这个位置又不破坏堆的性质,那么插入完成,否则,就将把它的父节点的元素移入该空穴,这样,空穴就向上移了一层。直到符合堆的性质。
void Insert( ElementType X,PriorityQueue H ) { int i; if( IsFull( H ) ) { Error( "Priority queue is full" ); return; } for( i = ++H->Size; H->Elements[ i / 2 ] > X; i /= 2 ); H->Elements[ i ] = H->Elements[ i / 2 ]; H->Element[ i ] = X; }
也可以先将X放入空穴,然后与父节点比较,不符合的话就交换,但是这样时间较慢。
如果插入的数时新的最小值,那么将一直上升到顶端,i=1,那么需要跳出for循环,令位置0处的值足够小就可以了,称之为标记。
4:DeleteMin
当删除一个最小元时,在根节点处产生了一个空穴,需要将最后一个元素正确的移入空穴。将空穴的两个儿子中的较小者放入空穴中,重复该步骤直到可以将堆中最后一个元素放入空穴中。
Element DeleteMin( PriorityQueue H ) { int i,child; ElementType MinElement,LastElement; if( IsEmpty( H ) ) { Error( "Priority queue is empty" ); return h->Elements[ 0 ]; } MinElement = H->Elements[ 1 ]; LastElement = H->Elements[H->Size--]; for( i = 1; i * 2 <= H->Size; i = child ) { child = i * 2; if( child != H->Size && H->Elements[ child + 1 ] < H->Elements[ child ] )//判断左右儿子大小 child++; if( LastElement > H->Elements[ child ] )//判断最后一个元素与当前空穴的较小儿子的大小,是否可以插入空穴 H->Elements[ i ] = H->Elements[ child ]; else break; } H->Elements[ i ] = LastElement; return MinElement; }
相关文章推荐
- 初学hadoop之--------java中的for each语句----for (IntWritable val : values)
- cannot restore segment prot after reloc: Permission denied
- TCP/IP协议栈的基本工作原理
- java静态代理
- 思科网院大赛
- WIN7 VS2010配置Openssl
- templete_cutv and cute
- C++ 友元
- 开发Struts 2项目遇到的一个问题,就是在struts-tags标签库下没有了s:datetimepicker标签的解决办法
- .net导出Excel几种方式比较
- MySQL 1165 错误解决办法
- PHP漏洞全解(七)-Session劫持
- 英语单词拟声
- IOS --控件UITextField详解
- 棋盘问题 dfs()基本的
- 基于crontab的mysql自动备份
- 数字签名和数字证书
- socket编程原理
- KDD
- viewController详解