优先队列的简单实现-二叉堆实现
2017-01-21 20:08
627 查看
二叉堆
二叉堆简介二叉堆是优先队列的一种实现方式
同二叉查找树一样,二叉堆也有结构性和堆序性
结构性
堆是一棵除底层外完全被填满的树
堆序性
使操作被快速执行的性质是堆序性。在这里,我们想实现的是快速找出最小值(最大值),因此最小值(最大值)应该在根上。
所以我们可以得出一个堆序性:在堆中,对于每一个节点X,X的父亲的值应该小于等于(大于等于)X的值。
如果你不知道二叉树这些知识,建议先自行了解这些知识
下面先给出关键的源代码,稍后再作分析
优先队列
头文件代码BinHeap.h
#ifndef BINHEAP_H_INCLUDED #define BINHEAP_H_INCLUDED struct HeapStruct; typedef struct HeapStruct *PriorityQueue; PriorityQueue Initialize( int MaxElements ); void Destroy( PriorityQueue H ); void MakeEmpty( PriorityQueue H ); void Inser( ElementType X,PriorityQueue H ); ElementType DeleteMin( PriorityQueue H ); ElementType FindMin( PriorityQueue H ); int IsEmpty( PriorityQueue H ); int IsFull( PriorityQueue H ); #endif // BINHEAP_H_INCLUDED
具体实现
BinHeap.c
#include <stdio.h> #include <stdlib.h> #include "BinHeap.h" 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!!!" ); /* Allocate the array plus one extra for sentinel */ 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; } 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->Elements[ i ] = X; } ElementType 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; }
代码分析
为什么用数组来实现二叉堆
因为“实惠”因为二叉堆有个特点是:除了最底层,其他层都必须是满的,也就是一棵二叉完全树
比如上图中,一共有十个节点,那么用数组就可以这样来存
1 2 3 4 5 6 7 8 9 10
下标为1-10
那么的节点1的儿子的下标就是2*1,2*1+1
节点5的父亲便是5/2 = 2
这样很方便吧,写起来也简单
Insert操作
插入操作采取的是上滤首先我们在数组末端开一个空穴,然后把要插入的值放在空穴里面,之后比较空穴的父亲的值和插入的值的大小,
如果父亲的值教大,那么便交换空穴和父亲,一只重复这个操作,直到找到符合条件的位置
DeleteMin操作
删除最小元操作采取的是下滤下滤和上滤的思路是差不多的,只是过程相反,这里就不多说,留着读者自己思考吧
相关文章推荐
- 自己实现一个简单的优先队列-二叉堆
- 数据结构之优先队列--二叉堆(Java实现)
- 使用二叉堆实现优先队列
- 每日一省————使用二叉堆实现优先队列
- 优先队列的简单实现方式
- PriorityBlockingQueue优先队列的二叉堆实现
- 数据结构之优先队列--二叉堆(Java实现)
- 用二叉堆实现优先队列
- 二叉堆(binary heap)—— 优先队列的实现
- C#实现优先队列 基于二叉堆 附使用案例
- 简单优先队列实现-基于最小堆
- 优先队列(堆)——二叉堆的实现
- 数据结构之优先队列--二叉堆(Java实现)
- 二叉堆实现优先队列
- 优先队列的实现--二叉堆
- 数据结构_使用二叉堆实现优先队列
- 算法学习 - 优先队列的二叉堆实现
- 优先队列二叉堆 C语言实现
- 【数据结构】实现大小堆也叫二叉堆(类似c++中的优先队列)
- 优先队列--二叉堆实现