最小最大混合堆:
堆序性质为:偶数深度上的任意节点X,存储在X上的关键字小于它的父亲但是大于它的祖父;奇数深度上的任意节点X,存储在X上的关键字大于它的父亲但是小于它的祖父。如下图所示为根据下面的插入方法根据输入1 2 3 4 5 6 7 8 9 10生成的一个最小最大堆:

1、最小最大堆的插入方法
PriorityQueue MinMaxHeapInsert(PriorityQueue Q,int X)
{
if(IsFull(Q))
printf("Q is Full,can not insert!");
else
{
Q->size+=1;
int i=Q->size;
while(i)
{
float flag=log10(i*1.0)/log10(2.0);//C库中没有以2为底的求对数,只能变换一下
int jiou=(int(flag))%2;//得到i所在深度的奇偶,使用log2(i)%2得到
if(jiou==0)//偶数深度节点
{
if(i/2!=0&&Q->Arr[i/2]<X)//大于父节点互换,互换后i所在的深度奇偶变换,跳到下面的循环
{
Q->Arr[i]=Q->Arr[i/2];
Q->Arr[i/2]=X;
i=i/2;
}
else if(Q->Arr[i/4]>X)//小于祖父节点互换,互换后i所在的深度奇偶变换,跳到下面的循环
{
Q->Arr[i]=Q->Arr[i/4];
Q->Arr[i/4]=X;
i=i/4;
}
else//顺序正常不变,直接插入,循环结束
{
Q->Arr[i]=X;
break;
}
}
else//奇数深度节点
{
if(Q->Arr[i/2]>X)//小于父节点互换,互换后i所在的深度奇偶变换,跳到前面的循环
{
Q->Arr[i]=Q->Arr[i/2];
Q->Arr[i/2]=X;
i=i/2;
}
else if(i/4!=0&&Q->Arr[i/4]<X)//大于祖父节点互换,互换后i所在的深度奇偶变换,跳到前面的循环
{
Q->Arr[i]=Q->Arr[i/4];
Q->Arr[i/4]=X;
i=i/4;
}
else//顺序正常不变,直接插入,循环结束
{
Q->Arr[i]=X;
break;
}
}
}
}
return Q;
}
2、最小最大堆的DeleteMin操作
int DeleteMinMMHeap(PriorityQueue Q)
{
if(IsEmpty(Q))
{
printf("Empty PriorityQueue!");
return Q->Arr[0];
}
int mindata=Q->Arr[1];
int lastone=Q->Arr[Q->size--];
int i=1,minchild;
int min;
for(i=1;4*i<=Q->size;i=min)
{
min=4*i;
for(int j=min+1;j<=Q->size&&j<=4*i+3;j++)
{
if(Q->Arr[min]>Q->Arr[j])
min=j;
}
if(Q->Arr[min]<lastone)
Q->Arr[i]=Q->Arr[min];
else
break;
}
//递渐找到小值后,最后空出给lastone填充,
//填完后要看是否符合大小堆规则,不符合继续调整
//Q->Arr[i]=lastone;
if(2*i>Q->size)//i在最后一层没有子节点
{
if(Q->Arr[i/2]<lastone)
{
Q->Arr[i]=Q->Arr[i/2];
Q->Arr[i/2]=lastone;
}
else
Q->Arr[i]=lastone;
}
else if(2*i<=Q->size)//i在次一层可能有1个或2个子节点
{
minchild=2*i;
if((minchild!=Q->size)&&Q->Arr[minchild]>Q->Arr[minchild+1])
minchild++;
if(Q->Arr[minchild]<lastone)
Q->Arr[i]=Q->Arr[minchild];
Q->Arr[minchild]=lastone;
}
else if(4*i>Q->size)//i在次二层必有两个子节点
{
if(Q->Arr[i/2]<lastone)
{
Q->Arr[i]=Q->Arr[i/2];
Q->Arr[i/2]=lastone;
}
minchild=2*i;
if((minchild!=Q->size)&&Q->Arr[minchild]>Q->Arr[minchild+1])
minchild++;
if(Q->Arr[minchild]<Q->Arr[i])
{
int temp=Q->Arr[i];
Q->Arr[i]=Q->Arr[minchild];
Q->Arr[minchild]=temp;
}
else
Q->Arr[i]=lastone;
}
return mindata;
}
代码实现的有点粗糙和复杂,特别是删除的方法,也没有充分测试,不知道是否有更简便的方法
浙公网安备 33010602011771号