数据结构--堆

1 堆是一种树形数据结构

—它总是一颗完全二叉树

—堆中的某个结点总是不大于或不小于其父节点的值

—根节点的值为整个堆中的最小或最大值

2 父节点中的值大于等于(小于等于),根节点的值最大(最小)的堆称为大(小)根堆

3堆的建立

//初始化: 一个空数组,元素个数为0
const int maxn=10000;
int len=0;
int heap=[maxn+5];

4插入数据

:在堆中插入数据,,先将它放到数组末尾,再尝试逐个往上跳

//小根堆
void up(int k){
    while(k>1&&heap[k]<heap[k/2]){
        swap(heap[k],heap[k/2]);
        k/=2;//判断当前结点的位置是否比父节点小,如果小,就交换位置
    }
}
//大根堆
void up(int k){
    while(k>1&&heap[k]>heap[k/2]){
        swap(heap[k],heap[k/2]);
        k/=2;//判断当前结点的位置是否比父节点小,如果小,就交换位置
    }
}

5删除数据

:跟插入数据逆向思维,将要删除的元素与最后的元素交换,然后再去调整被交换的元素,如果是小根堆,每次取较小孩子交换值,如果是大根堆,每次取较大孩子交换–保证堆的性质

删除根节点:

//小根堆
void Pop(){
    swap(heap[1],heap[len]);//删除堆顶元素
    len--;
    Down(1);//此时堆顶元素为原来的heap[len]
}
void Down(int k){
    while(2*k<=len){
        //存在左孩子
        int i=2*k;
        if(i+1<=len&&heap[i+1]<heap[i]) i++;
        //如果右孩子存在并且右孩子的值小于小于左孩子
    }
    if(heap[k]<=heap[i]) break;//此时该数据已经比左右孩子都小,退出循环
    swap(heap[k],heap[i]);
    k=i;
}

删除任意结点:此时不仅要考虑下移,还有可能会上移

//小根堆
void delete(int p){
    if(p==len){
        heap[len]=0;
        len--;
        return;
    }
    int x=heap[p],y=heap[len];
    swap(heap[p],heap[len]);
    len--;
    if(y<x){
        //如果队尾的数比原来的数小,则交换后,它的孩子必定比它大,但是父亲结点不一定比它小
        up(p);
    }else{
        //如果队尾元素比原来的数大,则交换后,它的父亲结点一定比它小,但是左右孩子不一定比它大
        down(p);
    }
}

6 c++ stl 库中的priority_queue(优先队列)跟手写堆类似

priority_queue<int,vector<int>,greatr<int>> pq;//构造一个小根堆
pq.empty();
pq.size();
py.top();//访问队首元素,相当于堆顶元素
py.push(); py.pop();  

7 自定义排序

struct cmp1
{
	bool operator()(int a, int b)
	{
		return a < b;
	}
};
priority_queue<int, vector<int>, cmp1> pq;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值