今天打算学习左偏堆,可是想起来自己二叉堆都没有看懂,于是就跑去回顾二叉堆了。发现以前看不懂的二叉堆,今天看起来特简单,随手就写好了一个堆了。

  简单的说一下我对二叉堆操作的理解。我不从底层函数说上去,相反,我打算从实现来解释底层函数的构造,以大堆为例。

  其实操作都很简单,对于push函数,因为堆是一棵严格的完全二叉树,所以我们直接在队列的尾端插入新增加的元素。然后就将这个元素不停的跟他的父节点进行比较,如果这个元素更大就跟父节点交换,否则就退出上推更新这个操作。对于pop的操作也是差不多的,我们可以将出堆的元素的位置用最底的元素替换。然后就是将这个替换上堆顶的元素下推。对于当前这个元素的位置,如果左儿子比右儿子大,就用左儿子跟当前元素比较,如果左儿子比较大,就把左儿子交换上去。反之亦然。

通过简单测试的二叉堆代码如下:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <queue>
  6.  
  7. using namespace std;
  8.  
  9. const int Q = ;
  10. template<class T>
  11. struct PriQ {
  12. T q[Q];
  13. int sz;
  14. void clear() { sz = ;}
  15. void up(int k) {
  16. while (k > ) {
  17. if (q[k] < q[k >> ]) swap(q[k >> ], q[k]);
  18. else return ;
  19. k >>= ;
  20. }
  21. }
  22. void push(T x) {
  23. q[++sz] = x;
  24. up(sz);
  25. }
  26. void down(int k) {
  27. while ((k << ) <= sz) {
  28. if ((k << ) == sz || q[k << ] < q[k << | ]) {
  29. if (q[k << ] < q[k]) swap(q[k], q[k << ]);
  30. else return ;
  31. k = k << ;
  32. } else {
  33. if (q[k << | ] < q[k]) swap(q[k], q[k << | ]);
  34. else return ;
  35. k = k << | ;
  36. }
  37. }
  38. }
  39. void pop() {
  40. q[] = q[sz];
  41. sz--;
  42. down();
  43. }
  44. T top() { return q[];}
  45. int size() { return sz;}
  46. } ;
  47. PriQ<int> pq;

左偏堆将尽快更新~

UPD:

通过小数据测试的左偏堆代码实现(大堆):

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5.  
  6. using namespace std;
  7.  
  8. template<class T>
  9. struct Node {
  10. int d;
  11. T dt;
  12. Node *l, *r;
  13. Node() { l = r = NULL;}
  14. Node(T dt) : dt(dt), d() { l = r = NULL;}
  15. } ;
  16.  
  17. template<class T>
  18. Node<T> *merge(Node<T> *a, Node<T> *b) {
  19. if (!a) return b;
  20. if (!b) return a;
  21. if (a->dt < b->dt) return merge(b, a);
  22. a->r = merge(a->r, b);
  23. a->d = a->r ? a->r->d + : ;
  24. return a;
  25. }
  26.  
  27. template<class T>
  28. Node<T> *popTop(Node<T> *x) { return merge(x->l, x->r);}
  29.  
  30. template<class T>
  31. struct Leftist {
  32. Node<T> *rt;
  33. void clear() { rt = NULL;}
  34. T top() { return rt->dt;}
  35. void push(T dt) { rt = merge(rt, new Node<T>(dt));}
  36. void pop() { rt = popTop(rt);}
  37. } ;
  38.  
  39. Leftist<int> pq;
  40.  
  41. int main() {
  42. pq.clear();
  43. pq.push();
  44. pq.push();
  45. pq.push();
  46. pq.push();
  47. cout << pq.top() << endl;
  48. pq.pop();
  49. cout << pq.top() << endl;
  50. pq.pop();
  51. cout << pq.top() << endl;
  52. pq.pop();
  53. cout << pq.top() << endl;
  54. return ;
  55. }

  目前只支持基本的合并以及删除最大值的操作。

http://jidayangfei.blog.163.com/blog/static/1349366082010107114825861/

——written by Lyon

二叉堆&&左偏堆 代码实现的更多相关文章

  1. HDU 1512 Monkey King(左偏堆)

    爱争吵的猴子 ★★☆ 输入文件:monkeyk.in 输出文件:monkeyk.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] 在一个森林里,住着N只好斗的猴子.开始,他们各 ...

  2. 编程算法 - 二叉搜索树(binary search tree) 代码(C)

    二叉搜索树(binary search tree) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 二叉搜索树(binary search tree)能 ...

  3. PAT树_层序遍历叶节点、中序建树后序输出、AVL树的根、二叉树路径存在性判定、奇妙的完全二叉搜索树、最小堆路径、文件路由

    03-树1. List Leaves (25) Given a tree, you are supposed to list all the leaves in the order of top do ...

  4. 【BZOJ 1367】 1367: [Baltic2004]sequence (可并堆-左偏树)

    1367: [Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sample Ou ...

  5. 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树|可并堆-左偏树)

    2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...

  6. BZOJ 2809: [Apio2012]dispatching(可并堆 左偏树板题)

    这道题只要读懂题目一切好说. 给出nnn个点的一棵树,每一个点有一个费用vvv和一个领导力aaa,给出费用上限mmm.求下面这个式子的最大值ax∗∣S∣ ( S⊂x的子树, ∑iv[i]≤m )\la ...

  7. USACO Running Away From the Barn /// 可并堆 左偏树维护大顶堆

    题目大意: 给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于m的点有多少个 左偏树 https://blog.csdn.net/pengwill97/article/details/82 ...

  8. BZOJ1367 [Baltic2004]sequence 堆 左偏树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1367 题意概括 Description Input Output 一个整数R 题解 http:// ...

  9. BZOJ2333 [SCOI2011]棘手的操作 堆 左偏树 可并堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2333 题意概括 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i ...

随机推荐

  1. 洛谷P1147 连续自然数和 [2017年6月计划 数论01]

    P1147 连续自然数和 题目描述 对一个给定的自然数M,求出所有的连续的自然数段,这些连续的自然数段中的全部数之和为M. 例子:1998+1999+2000+2001+2002 = 10000,所以 ...

  2. Javascript实现信息滚动效果的方法

    <html><head><meta http-equiv="Content-Type" content="text/html; charse ...

  3. FTP权限问题解析,553 Can't open that file: Permission denied

    FTP上传文件,提示553 Can't open that file: Permission denied 原因: 目录的所属组,所属用户属于root, 导致FTP无法上传, 修改组和所属用户为www ...

  4. 阿里云出手SaaS生态,中国SaaS市场小而不强有望破解

    企业服务SaaS市场还有很大的增长空间.SaaS的鼻祖Salesforces今年5月迈上了千亿美元市值的门槛,再一次为ToB市场注入了兴奋剂.单单一个SaaS CRM,目前全球的市场规模就超过400亿 ...

  5. nested exception is org.hibernate.MappingException解决方案

    1.可能是因为映射文件( Order.hbm.xm)配置的class路径出错 <hibernate-mapping> <class name="com.web.bean.O ...

  6. C# 详解反射

    原博客:http://www.cnblogs.com/Stephenchao/p/4481995.html 两个现实中的例子: 1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的 ...

  7. 详解TCP三握四挥

    TCP握手协议 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接.第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确 ...

  8. Sublime Text3安装教程,配置教程,常用插件安装等方法

    前言: sublimeText3的特点: 1.Sublime Text 是一款跨平台代码编辑器,在Linux.OS X和Windows下均可使用. 2.Sublime Text 是可扩展的,并包含大量 ...

  9. JavaScript--放大镜

    上例图: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF- ...

  10. C/C++中运算符优先级汇总

    编程语言C运算符优先级 优先级1: ( ).[ ].->. . 含义:圆括号.下标运算符.指向结构体成员运算符.结构体成员运算符 优先级2:!.~.++.――.-.(类型).*.&.si ...