【最大堆的操作】完全二叉树建立最大堆/插入/删除结点C语言实现

5 篇文章 1 订阅
1 篇文章 0 订阅

最大堆的插入
步骤:
1.将新插入元素放在size+1的位置
2.向上过滤结点使之满足最大堆的特点
在这里插入图片描述
最大堆的删除
在这里插入图片描述

基本概念:对于一个完全二叉树,结点序号为i的左孩子是2i,右孩子是2i+1

步骤

1.堆是否为空(为空则无法删除)
2.若不为空,取出根结点的最大元素
3.将数组下标最大的一个元素提出来,放在根结点位置
4.从上到下过滤结点

heap->Data[heap->size]待比较元素 过滤结点的具体操作

4.1   parent*2<=heap->size//判别有没有左孩子
4.2 没有左孩子时,一定也没有右孩子,即为完全二叉树最下面一层,位置已找到
4.3 若有左孩子,并且child!=heap->size(判断有没有右孩子)时(即把上面判别有没有左孩子的条件中等号去掉),说明既有左孩子也有右孩子
4.4在有左右孩子时,比较两个孩子大小,如果右孩子大,那么child++,即为选择右孩子的路径向下过滤

代码

#include<stdio.h>
#include<malloc.h>
typedef struct heap{
    int *Data;
    int size;//当前数量
    int maxsize;//最大数量
}*Maxheap;
int Maxterm;
Maxheap gen(int Maxsize);
Maxheap insert(int X,Maxheap heap);
Maxheap delete();
Maxheap gen(int Maxsize)
{
    Maxheap heap;
    heap=(Maxheap)malloc(sizeof(struct heap));
    heap->Data=(int *)malloc(sizeof(int)*(Maxsize+1));
    heap->maxsize=Maxsize;
    heap->size=0;
    heap->Data[0]=100000;

    return heap;
}
Maxheap insert (int X,Maxheap heap)
{
    if(heap->maxsize==heap->size)//堆已满
       return heap;
    else
    {
        int temp=(heap->size+1);
        while(heap->Data[temp/2]<X)
        {
            heap->Data[temp]=heap->Data[temp/2];
            temp=temp/2;
        }
        heap->Data[temp]=X;
        return heap;
    }
}
Maxheap delete(Maxheap heap)
{
    if(heap->size==0)//最大堆为空
      return heap;
    else 
    {
        Maxterm=heap->Data[1];
        int temp=heap->Data[heap->size];
        heap->size--;
        heap->Data[1]==heap->Data[heap->size];

        int parent=1;
        int child;
        int idx=heap->Data[heap->size];
        for(parent=1;parent*2<=heap->size;parent=child)//有左孩子
        {
            child = parent*2;
            if((child!=heap->size)&&(heap->Data[child]<heap->Data[child+1]))//有右孩子且右孩子大于左孩子
              child++;//选这条路径
            if((temp>=heap->Data[child]))//已经找到位置,比左右孩子中最大的一个元素还大
              break;
            else//还没有找到,继续向下寻找
              heap->Data[parent]=heap->Data[child];        
        }
        heap->Data[parent]=temp;//将待比较元素放在合适的位置
        return heap;
     
    }
}
**建立最大堆**
类似于最大堆的删除,从最后一个父结点到第一个结点,依次向下过滤,使其满足最大堆的特性。

```c
/*----------- 建造最大堆 -----------*/
void PercDown( Maxheap H, int p )
{ /* 下滤:将H中以H->Data[p]为根的子堆调整为最大堆 */
    int Parent, Child;
    int 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 BuildHeap( Maxheap H )
{ /* 调整H->Data[]中的元素,使满足最大堆的有序性  */
  /* 这里假设所有H->Size个元素已经存在H->Data[]中 */
 
    int i;
 
    /* 从最后一个结点的父节点开始,到根结点1 */
    for( i = H->size/2; i>0; i-- )
        PercDown( H, i );
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值