二叉堆(Binary_Heap)

来源:互联网 发布:r语言 数据挖掘 编辑:程序博客网 时间:2024/05/22 05:09

      二叉堆满足其结构性,堆序性。结构性:要求为完全二叉树,即除树的最底层外,树被完全填满,且底层的元素从左向右填充。堆序性:即在堆中要求,对任意元素X,X的父节点的关键字小等于X的关键字,如此得到最小堆。同理可得最大堆。  由于堆序性,因此二叉堆也常称为实现优先队列(Priority Queue)。

      在对二叉堆进行操作时需要始终保持其结构性和堆序性。可用数组来实现二叉堆。数组中的元素关系为:i位置上的节点,其左儿子在2i上,右节点在2i+1上,父节点在i/2(取整)上。用数组代替树结构,从而不用包含指针操作。


具体实现代码如下:

Binary_Heap.h:

#ifndef _BINARY_HEAP_#define __BINARY_HEAP_class HeapStruct;typedef HeapStruct* Heap;typedef int ElementType;Heap Initialize(int MaxElement);void Distory(Heap H);void MakeEmpty(Heap H);void Insert(ElementType X,Heap H);ElementType DeleteMin(Heap H);ElementType FindMin(Heap H);int IsEmpty(Heap H);int IsFull(Heap H);struct HeapStruct {int Capacity;int Size;ElementType *Elements;};int MinData=-1;//用于标记#endif

Binary_Heap.c:

#include "Binary_Heap.h"#include <stdio.h>Heap Initialize(int MaxElement){if (MaxElement<=0)return nullptr;Heap H=new HeapStruct;if(nullptr==H){printf("out of Space \n");return nullptr;    }H->Elements=new ElementType[MaxElement+1];//第一个元素为MinData标记if(nullptr==H->Elements){printf("Out of Space \n");return nullptr;}H->Capacity=MaxElement;H->Size=0;H->Elements[0]=MinData; return H;}void Distory( Heap H){if(H->Elements!=nullptr)delete[] H->Elements;delete H;}void MakeEmpty(Heap H){if(H->Elements!=nullptr)delete[] H->Elements;H->Elements=nullptr;H->Size=0;}int IsEmpty(Heap H){if(0==H->Size)return 1;else return 0;}int IsFull(Heap H){if(H->Size==H->Capacity)return 1;else return 0;}//在尾部插入新元素,并进行上滤操作,直到满足堆序性。//注意:必满显示的交换赋值操作void Insert(ElementType X,Heap H){if(IsFull(H))return;int i;for( i=++H->Size;H->Elements[i/2]>X;i/=2)//用MinData标记来防止i/2越界H->Elements[i]=H->Elements[i/2];H->Elements[i]=X;//避免显示交换的赋值}//删除头部的最小元,并对空穴进行下滤操作,直到满足堆序性。//注:如何避免显示的交换赋值操作ElementType DeleteMin(Heap H){ if(IsEmpty(H))return H->Elements[0]; int Child ,i; ElementType TempCell; ElementType MinElement=H->Elements[1]; ElementType LastElement=H->Elements[H->Size--]; for( i=1;i*2<=H->Size;i=Child)//对空穴进行下滤操作,直到满足堆序性 { Child=i*2; if(Child!=H->Size && H->Elements[Child]>H->Elements[Child+1])//有右儿子,且右儿子更小 ++Child; if(LastElement>H->Elements[Child]) H->Elements[i]=H->Elements[Child]; else  break; } H->Elements[i]=LastElement;//最后才将该值真正放到空穴中去,避免了显示的交换操作(将两次赋值减少为一次) return MinElement;}ElementType FindMin(Heap H){if(IsEmpty(H))return H->Elements[0];else return H->Elements[1];}
//简单测试void main(){Heap H=Initialize(20);int A[]={12,2,21,2,45,4,23,4,19,6,21,31,25,22};for(int i=0;i<14;++i)Insert(A[i],H);for(int i=0;i<14;++i)A[i]=DeleteMin(H);for(int i=0;i<14;++i)//将得到的排序后的元素输出。这也正是堆排序的基本思想printf("%d ",A[i]);}


0 0
原创粉丝点击