think:
1 今天上午学习了树中的堆结构将一些对结构的基本操作写了写,记录下来,后续继续优化。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ElementType int
#define MAXDATA 20000/* 根据具体情况定义为大于堆中所有可能元素的值*/
#define MINDATA -1/* 根据具体情况定义为小于堆中所有可能元素的值*/
typedef struct HNode *Heap;///堆的类型定义
struct HNode{
ElementType *Data;//存储元素的数组
int Size;//堆中当前元素个数
int Capacity;//堆的最大容量
};
typedef Heap MaxHeap;//最大堆
typedef Heap MinHeap;//最小堆
MaxHeap CreatHeap(int MaxSize)
{/* 创建容量为MaxSize的空的最大堆*/
MaxHeap H = (MaxHeap)malloc(sizeof(struct HNode));
H->Data = (ElementType *)malloc((MaxSize+1)*sizeof(ElementType));
H->Size = 0;
H->Capacity = MaxSize;
//H->Data[0] = MAXDATA;
return H;
}
void MaxInsert(MaxHeap H, ElementType X)
{//将元素X插入最大堆H
H->Data[0] = MAXDATA;//定义“哨兵”
int i;
i = ++H->Size;
for(;H->Data[i/2] < X; i /= 2)
{
H->Data[i] = H->Data[i/2];
}
H->Data[i] = X;
}
void MinInsert(MinHeap H, ElementType X)
{//将元素X插入最小堆H
H->Data[0] = MINDATA;//定义“哨兵”
int i;
i = ++H->Size;
for(;H->Data[i/2] > X; i /= 2)
{
H->Data[i] = H->Data[i/2];
}
H->Data[i] = X;
}
ElementType DeleteMax(MaxHeap H)
{/* 从最大堆中取出键值为最大的元素,并删除一个结点*/
int Parent, Child;
ElementType MaxItem, X;
MaxItem = H->Data[1];
X = H->Data[H->Size--];
for(Parent = 1; Parent*2 <= H->Size; Parent = Child)
{
Child = Parent*2;
if((Child != H->Size) && H->Data[Child] < H->Data[Child+1])
Child++;
if(X >= H->Data[Child])
break;
else
H->Data[Parent] = H->Data[Child];
}
H->Data[Parent] = X;
return MaxItem;
}
ElementType DeleteMin(MinHeap H)
{/* 从最小堆中取出一个键值最小的元素,并删除一个结点*/
int Parent, Child;
ElementType MinItem, X;
MinItem = H->Data[1];
X = H->Data[H->Size--];
for(Parent = 1; Parent*2 <= H->Size; Parent = Child)
{
Child = Parent*2;
if((Child != H->Size) && H->Data[Child] > H->Data[Child+1])
Child++;
if(X <= H->Data[Child])
break;
else
H->Data[Parent] = H->Data[Child];
}
H->Data[Parent] = X;
return MinItem;
}
void PercDown1(MaxHeap H, int p)
{/* 下滤, 将H中以H->Data[p]为根的子堆调整为最大堆*/
int Parent, Child;
ElementType X;
X = H->Data[p];//取出根节点存放的值
for(Parent = p; Parent*2 < H->Size; Parent = Child)
{
Child = Parent*2;
if((Child != H->Size) && H->Data[Child] < H->Data[Child+1])
Child++;/* Child指向左右结点中的较大者*/
if(X >= H->Data[Child])//找到了合适的位置
break;
else//下滤X
H->Data[Parent] = H->Data[Child];
}
H->Data[Parent] = X;
}
void BuildHeap1(MaxHeap H)
{/* 调整H->Data[]中的元素,使得满足最大堆的有序性*/
/* 这里假设所有H->Size个元素已经存在H->Data[]中*/
int i;
/* 从最后一个结点的父结点开始,到根结点1*/
for(i = H->Size/2; i > 0; i--)
PercDown1(H, i);
}
void PercDown2(MinHeap H, int p)
{/* 下滤, 将H中以H->Data[p]为根的子堆调整为最小堆*/
int Parent, Child;
ElementType X;
X = H->Data[p];//取出根节点存放的值
for(Parent = p; Parent*2 <= H->Size; Parent = Child)
{
Child = Parent*2;
if((Child != H->Size) && H->Data[Child] > H->Data[Child+1])
Child++;/* Child指向左右结点中的较小者*/
if(X <= H->Data[Child])//找到了合适的位置
break;
else//下滤X
H->Data[Parent] = H->Data[Child];
}
H->Data[Parent] = X;
}
void BuildHeap2(MinHeap H)
{/* 调整H->Data[]中的元素,使得满足最小堆的有序性*/
/* 这里假设所有H->Size个元素已经存在H->Data[]中*/
int i;
/* 从最后一个结点的父结点开始,到根结点1*/
for(i = H->Size/2; i > 0; i--)
PercDown2(H, i);
}