数据结构——堆

一、什么是堆?

堆是一类树形的数据结构。分为大顶堆(最大堆)和小顶堆(最小堆)。

  • 小顶堆的特点:儿子节点的值不小于父亲节点的值,堆顶元素是最小值
  • 大顶堆的特点:儿子节点的值不大于父亲节点的值, 堆顶元素是最大值

堆可以被看做是一种完全二叉树结构。所以通常用数组实现,( 用指针也可以实现,比较麻烦)

二、小顶堆的实现
1、堆有两只操作:

①一种是压入(push)元素操作
②一种是压出(pop)堆顶元素操作

2、push操作:

这一操作,是将新的元素压入。压入一个元素很简单。 但是压入的同时,你还要维护它原来的特点, 否则就不叫堆了。

对于压入一个元素x的过程如下:
①暂时将这个元素x放到堆的最后一个节点编号的位置
②然后,跟父亲作比较,判断是否这个值x要向上浮(个人感觉这个浮很形象),同时他的父亲就要向下沉
③重复②直到,x不小于父亲的值。

3、pop操作:

这个操作也是, 压出堆顶很简单, 重要的是要维护它的状态,具体流程如下:

①将堆顶的值赋给r变量ret, 用于返回这个值
②将堆的最后一个元素x提到堆顶。
③然后就, 跟他的儿子比较, 判断是否这个值x要向下沉, 同时他的最小的那个儿子要向上浮
④重复③操作, 知道儿子的值不小于x。

#include<stdio.h>
#include<stdlib.h>

#define MAXN 50000

int heap[MAXN], sz = 0;// 堆数组, 和堆大小。

void push(int x)//压入堆操作。
{
    int i = sz++;// i表示x开始要插入的位置

    while(i > 0)//x的位置上限是0,所以i==0时,就停止操作
    {
        int p = (i - 1)/2; // p为 i的父亲的下标   

        if(x >= heap[p])break;// x 不小于 父亲的值就结束

        //否沉则, 将父亲的值往下
        heap[i] = heap[p];
        i = p;// x的位置向上浮
    }

    heap[i] = x;// 将x的值 赋给它最终位置上。
}

int pop()
{
    // 取出堆顶
    int ret = heap[0];
    
    int x = heap[--sz];// x是最后一个元素 
    
    int i = 0;// x的位置
    
    while(i*2+1 <sz)
    {
        int l = i*2+1, r = i*2+2;// 左儿子 和右儿子
        int min;
        if(r < sz &&heap[r] < heap[l]) min = r;
        else min = l;
        
        if(heap[min] >= x)break;// 如果最小的那个儿子的值 不小于 x, 就结束
        //否则
        heap[i] = heap[min];// 最小的儿子向上浮 
        i = min;// x的位置向下沉
    }
    heap[i] = x;// 最终将x赋给 他所在的位置
    return ret;
    
}
int main()
{


    return 0;
}

三、 大顶堆其实差不多, 只是修改比较的标准。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值