最小堆

最小堆是堆的两种形式之一,与最大堆结构类似,不过最小堆中任意结点都是左右子树中的最小值,代码实现和最大堆类似。在上一片博客中已经介绍过最大堆,所以在这里不再赘述。此为链接:最大堆
以下为代码实现:

#include<stdio.h>
#include<malloc.h>

#define ElementType int
#define MaxData -99999  //哨兵
#define MaxSize 100  //堆的最大空间

typedef struct Heap *MinHeap;
struct Heap
{
    ElementType *element;  //存储元素
    int size;  //元素的数量
    int capacity; //堆的最大空间
};

//创建最小堆
MinHeap Creat(int n)
{
    ElementType tmp;
    int parent, child, i;
    MinHeap H = (MinHeap)malloc( sizeof(struct Heap) );
    H->element = (ElementType*)malloc( (MaxSize+1) * sizeof(ElementType) );
    H->size = n;
    H->capacity = MaxSize;
    H->element[0] = MaxData;
    for( i = 1; i <= H->size; i++ )     //将元素按输入顺序放入数组中
    {
        scanf("%d", &H->element[i]);
    }
    for( i = H->size / 2; i >= 1; --i)     //将数组中的元素调成最小堆
    {
        tmp = H->element[i];
        for( parent = i; parent*2 <= H->size; parent = child )
        {
            child = parent * 2;
            if(child != H->size && H->element[child+1] < H->element[child])
                child++;          //child指向左右儿子中较小的那个;
            if( tmp <= H->element[child] )   //如果tmp小于等于左右儿子中较小的那个,结束循环
                break;
            else                    //否则,较小的儿子上移,tmp进入下一层
                H->element[parent] = H->element[child];
        }
        H->element[parent] = tmp;
    }

    return H;
}

//插入一个元素
void Insert(MinHeap H, ElementType e)
{
    int i;
    if( H->size == H->capacity )   //判断堆是否已满
    {
        printf("堆已满!");
        return ;
    }
    i = ++H->size;  //所存元素数量加1
    for( ; H->element[i/2] > e; i /= 2)  //当要插入的元素小于父节点时,父节点向下挪动,要插入的元素继续向上比较
        H->element[i] = H->element[i/2];
    H->element[i] = e;
}

//删除根结点并返回其值
ElementType Delete(MinHeap H)
{
    int parent, child;
    ElementType tmp, e;
    int i;
    if( H->size == 0)
    {
        printf("堆为空!");
        return 0;
    }
    e = H->element[1];
    tmp = H->element[H->size--];
    for( parent = 1; parent*2 <= H->size; parent = child )
    {
        child = parent * 2;
        if(child != H->size && H->element[child+1] < H->element[child])
            child++;          //child指向左右儿子中较小的那个;
        if( tmp <= H->element[child] )   //如果tmp小于等于左右儿子中较小的那个,结束循环
            break;
        else                    //否则,较小的儿子上移,tmp进入下一层
            H->element[parent] = H->element[child];
    }
    H->element[parent] = tmp;
    return e;

}

//层序遍历输出堆
void Print( MinHeap H )
{
    int i;
    for( i = 1; i <= H->size; i++ )
    {
        printf("%d ", H->element[i]);
    }
    printf("\n");
}

int main()
{
    int n;
    ElementType i, e;
    MinHeap H;
    scanf("%d", &n);
    H = Creat(n); //创建最小堆
    printf("\n堆中的元素为: ");
    Print(H);
    printf("删除的元素为: %d",  Delete(H));
    printf("\n删除根结点后为: ");
    Print(H);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值