最近学习了怎样构造最大堆和最小堆,小有收获。
堆有两个特性:
结构性:用数组表示的完全二叉树
有序性:任一结点的关键字是其子树所有节点所有节点的最大值(最小值)
最大堆的初始化
struct HeapStruct
{
ElementType *Elements;//用来存储堆元素的数组
int Size;//当前堆存储元素的个数
int Capacity;//最大存储堆的元素的个数
};
typedef struct HeapStruct* MaxHeap;
MaxHeap Create(int MaxSize)//创建堆
{
MaxHeap H=(MaxHeap)malloc(sizeof(struct HeapStruct));
H->Elements=(MaxHeap)malloc((MaxSize+1)*sizeof(ElementType));
H->Size=0;
H->Capacity=MaxSize;
H->Elements[0]=MAXVALUE;//哨兵
return H;
}
堆的插入
void Insert(MaxHeap H,ElementType item)
{
int i;
if(IsFull) { printf("最大堆已满");return;}
i=++H->Size;//插入的位置
for(;H->Elements[i/2]<item&&i>1;i/=2)//(i>1)可省略
H->Elements[i]=H->Elements[i/2];
H->Elements[i]=item;
}
堆的删除
ElementType DeleMax(MaxHeap H)//从最大堆中取出键值最大的元素并删除
{
int Parent,Child;
ElementType MaxItem,temp;
if(IsEmpty(H)){
printf("最大堆已为空"); return;
}
MaxItem = H->Elements[1];
//用最大堆中最后一个元素从根节点开始向上过滤下层结点
temp=H->Elements[H->Size--];
for(Parent=1;Parent*2<=H->Size;Parent=Child)
{
Child=Parent*2;
if((Child!=H->Size)//是否存在右孩子
&&(H->Elements[Child]<H->Elements[Child+1]))
Child++;//Child指向左右子节点的最大点
if(temp>=H->Elements[Child]) break;
else H->Elements[Parent]=H->Elements[Child];//移动temp元素到下一层
}
H->Elements[Parent]=temp;
return MaxItem;
}