二叉堆&&左偏堆 代码实现
今天打算学习左偏堆,可是想起来自己二叉堆都没有看懂,于是就跑去回顾二叉堆了。发现以前看不懂的二叉堆,今天看起来特简单,随手就写好了一个堆了。
简单的说一下我对二叉堆操作的理解。我不从底层函数说上去,相反,我打算从实现来解释底层函数的构造,以大堆为例。
其实操作都很简单,对于push函数,因为堆是一棵严格的完全二叉树,所以我们直接在队列的尾端插入新增加的元素。然后就将这个元素不停的跟他的父节点进行比较,如果这个元素更大就跟父节点交换,否则就退出上推更新这个操作。对于pop的操作也是差不多的,我们可以将出堆的元素的位置用最底的元素替换。然后就是将这个替换上堆顶的元素下推。对于当前这个元素的位置,如果左儿子比右儿子大,就用左儿子跟当前元素比较,如果左儿子比较大,就把左儿子交换上去。反之亦然。
通过简单测试的二叉堆代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue> using namespace std; const int Q = ;
template<class T>
struct PriQ {
T q[Q];
int sz;
void clear() { sz = ;}
void up(int k) {
while (k > ) {
if (q[k] < q[k >> ]) swap(q[k >> ], q[k]);
else return ;
k >>= ;
}
}
void push(T x) {
q[++sz] = x;
up(sz);
}
void down(int k) {
while ((k << ) <= sz) {
if ((k << ) == sz || q[k << ] < q[k << | ]) {
if (q[k << ] < q[k]) swap(q[k], q[k << ]);
else return ;
k = k << ;
} else {
if (q[k << | ] < q[k]) swap(q[k], q[k << | ]);
else return ;
k = k << | ;
}
}
}
void pop() {
q[] = q[sz];
sz--;
down();
}
T top() { return q[];}
int size() { return sz;}
} ;
PriQ<int> pq;
左偏堆将尽快更新~
UPD:
通过小数据测试的左偏堆代码实现(大堆):
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; template<class T>
struct Node {
int d;
T dt;
Node *l, *r;
Node() { l = r = NULL;}
Node(T dt) : dt(dt), d() { l = r = NULL;}
} ; template<class T>
Node<T> *merge(Node<T> *a, Node<T> *b) {
if (!a) return b;
if (!b) return a;
if (a->dt < b->dt) return merge(b, a);
a->r = merge(a->r, b);
a->d = a->r ? a->r->d + : ;
return a;
} template<class T>
Node<T> *popTop(Node<T> *x) { return merge(x->l, x->r);} template<class T>
struct Leftist {
Node<T> *rt;
void clear() { rt = NULL;}
T top() { return rt->dt;}
void push(T dt) { rt = merge(rt, new Node<T>(dt));}
void pop() { rt = popTop(rt);}
} ; Leftist<int> pq; int main() {
pq.clear();
pq.push();
pq.push();
pq.push();
pq.push();
cout << pq.top() << endl;
pq.pop();
cout << pq.top() << endl;
pq.pop();
cout << pq.top() << endl;
pq.pop();
cout << pq.top() << endl;
return ;
}
目前只支持基本的合并以及删除最大值的操作。
http://jidayangfei.blog.163.com/blog/static/1349366082010107114825861/
——written by Lyon
二叉堆&&左偏堆 代码实现的更多相关文章
- HDU 1512 Monkey King(左偏堆)
爱争吵的猴子 ★★☆ 输入文件:monkeyk.in 输出文件:monkeyk.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] 在一个森林里,住着N只好斗的猴子.开始,他们各 ...
- 编程算法 - 二叉搜索树(binary search tree) 代码(C)
二叉搜索树(binary search tree) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 二叉搜索树(binary search tree)能 ...
- PAT树_层序遍历叶节点、中序建树后序输出、AVL树的根、二叉树路径存在性判定、奇妙的完全二叉搜索树、最小堆路径、文件路由
03-树1. List Leaves (25) Given a tree, you are supposed to list all the leaves in the order of top do ...
- 【BZOJ 1367】 1367: [Baltic2004]sequence (可并堆-左偏树)
1367: [Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sample Ou ...
- 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树|可并堆-左偏树)
2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...
- BZOJ 2809: [Apio2012]dispatching(可并堆 左偏树板题)
这道题只要读懂题目一切好说. 给出nnn个点的一棵树,每一个点有一个费用vvv和一个领导力aaa,给出费用上限mmm.求下面这个式子的最大值ax∗∣S∣ ( S⊂x的子树, ∑iv[i]≤m )\la ...
- USACO Running Away From the Barn /// 可并堆 左偏树维护大顶堆
题目大意: 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于m的点有多少个 左偏树 https://blog.csdn.net/pengwill97/article/details/82 ...
- BZOJ1367 [Baltic2004]sequence 堆 左偏树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1367 题意概括 Description Input Output 一个整数R 题解 http:// ...
- BZOJ2333 [SCOI2011]棘手的操作 堆 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2333 题意概括 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i ...
随机推荐
- python实例 输出你好
#打开新窗口,输入: #! /usr/bin/python # -*- coding: utf8 -*- s1=input("Input your name:") print(&q ...
- Liferay 7:如何在Liferay Portlet中使用Angular, React, Vue.js等前端框架
https://web.liferay.com/zh/web/ivan.zaera/blog/-/blogs/modern-frontend-workflows-in-liferay-portal L ...
- 机器学习之决策树(ID3)算法与Python实现
机器学习之决策树(ID3)算法与Python实现 机器学习中,决策树是一个预测模型:他代表的是对象属性与对象值之间的一种映射关系.树中每个节点表示某个对象,而每个分叉路径则代表的某个可能的属性值,而每 ...
- fedora安装mod_python
3.1 Installing mod_python To install mod_python, we simply run: yum install mod_python 3.2 Configuri ...
- 50道python面试题
1.大数据的文件读取 ① 利用生成器generator ②迭代器进行迭代遍历:for line in file 2.迭代器和生成器的区别 1)迭代器是一个更抽象的概念,任何对象,如果它的类有next方 ...
- PHPCMS网站迁移过程后,添加内容 报500错误解决方案
问题出现原因:1.网站迁移过程中,上传下载文件时文件丢失 2.PHPCMS源码更新升级 解决方法 1.可以到官方下载最新版源码,替换过去.如果对源码有改动,需要先保存改动过的文件,替换过去之后,再替 ...
- php表单和缩略图处理类是什么样呢
<?php//封装一个表单验证类//中文验证.邮箱验证.电话号码.手机.QQ.身份证.(由字母.数字.下划线组成,不能以数字开头)header('content-type:text/html;c ...
- 介绍elasticsearch的文件
elasticsearch.yml文件 打开上边的文件,我们看到下面的"集群"名称,节点名称 下图是文件的存储路径和日志路径 下面是监听的地址,默认是本机 下图指的是,集群是怎样搭 ...
- oracle如何加固你的数据库
要注意以下方面 1. 修改sys, system的口令. 2. Lock,修改,删除默认用户: dbsnmp,ctxsys等. 3. 把REMOTE_OS_AUTHENT改成False,防止远程机器直 ...
- redis 如何查看版本
./redis-cli -h 127.0.0.1 info | grep 'redis_version' redis-server -v