二叉堆:

  以前写过二叉堆,但很少使用,快忘了。最近又查了一些关于堆的资料,于是重新熟悉一下这种数据结构。

  一个快速又简单的方式建立二叉堆,仅使用简单vector(或者数组也行):

#include "stdafx.h"
#include <iostream>
#include <vector> #define LeftChild(i) ((i << 1) | 1)
#define RightChild(i) (i << 1) template<class T>
void swap(T & a, T & b)
{
T tem = a;
a = b;
b = tem;
} class Heap {
public:
/* 上滤插入 */
void up_insert(int val, std::vector<int> & values, int top); /* 调用上滤插入建立堆 */
void up2build(std::vector<int> & values); /* 下滤插入 */
void down_insert(std::vector<int> & values, int i, int size); /* 调用下滤插入建立堆 */
void down2build(std::vector<int> & values); /* 堆排序 */
void sort(std::vector<int> & values);
}; void Heap::up_insert(int val, std::vector<int> & values, int top)
{
size_t i;
for (i = top; i > 0 && values[i >> 1] < val; i >>= 1)
values[i] = values[i >> 1];
values[i] = val;
} void Heap::up2build(std::vector<int> & values)
{
int top = 0;
for (auto v : values)
{
up_insert(v, values, top);
++top;
}
} void Heap::down_insert(std::vector<int> & values, int i, int size)
{
int last = values[i];
for (int Child; LeftChild(i) < size; i = Child)
{
Child = LeftChild(i);
if (Child != size - 1 && values[Child + 1] > values[Child])
Child++; if (last < values[Child])
values[i] = values[Child];
else
break;
}
values[i] = last;
} void Heap::down2build(std::vector<int> & values)
{
int size = values.size() - 1;
for (int i = size >> 1; i >= 0; i--)
{
down_insert(values, i, size);
}
} void Heap::sort(std::vector<int> & values)
{
int size = values.size() - 1;
down2build(values);
for (int i = size; i > 0; i--)
{
swap(values[0], values[i]);
down_insert(values, 0, i);
}
} int main()
{
Heap heap;
std::vector<int> values { 5345,332,2341,498,248,89,239,4825,8,43,9892,872,1843 }; //heap.build(values);
heap.sort(values); for (auto v : values)
std::cout << v << std::endl; getchar();
return 0;
}

  up_build是形如‘上滤’的过程,平均情况时间复杂度为θ(n),因为up_insert函数平均只花费θ(1)的时间。空间复杂度O(n);

  down_build是形如‘下滤’的过程,时间复杂度为O(nlgn),空间复杂度O(n)。

 左式堆:

  左式堆的性质:任意节点的左孩子的NPL(null path length - 零路径长)至少等于右孩子的NPL,这样的条件使得左式堆十分不平衡。左式堆的基本操作是进行堆合并。

  NPL的定义:任一节点到叶节点的最短路径的长。

  参考资料:

    1.《数据结构与算法分析》第6章 - 堆。

    2.知乎相关问题

heap(堆)的更多相关文章

  1. Heap堆的理解以及在IAR中如何设置堆的大小

    文章首发于浩瀚先森博客 堆栈的概念在脑海里已经存在有一段时间了,今天就测试来整理下Heap堆.栈以后再说. 堆区不像全局变量和局部变量总是有指定的内存大小,它是为了在程序运行时动态分配内存而设定的一块 ...

  2. java - Stack栈和Heap堆的区别

    首先分清楚Stack,Heap的中文翻译:Stack—栈,Heap—堆.         在中文里,Stack可以翻译为“堆栈”,所以我直接查找了计算机术语里面堆和栈开头的词语:        堆存储 ...

  3. Heap(堆)和stack(栈)有的区别是什么。

    java的内存分为两类,一类是栈内存,一类是堆内存.栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个 ...

  4. JAVA Stack栈和Heap堆的区别(转)

          首先分清楚Stack,Heap的中文翻译:Stack—栈,Heap—堆.         在中文里,Stack可以翻译为“堆栈”,所以我直接查找了计算机术语里面堆和栈开头的词语:      ...

  5. 逻辑运算符、三元运算符、for循环、stack(栈),heap(堆),方法区,静态域

    Lesson One 2018-04-17 19:58:39 逻辑运算符(用于逻辑运算,左右两边都是 true 或 false) 逻辑与-& 和 短路与-&& 区别: & ...

  6. Stack栈 Heap堆

    Stack(栈) 栈(stack) 又名堆栈,它是一种运算受限的线性表.其限制是仅允许在表的一端进行插入和删除运算.这一端被称为栈顶,相对地,把另一端称为栈底.向一个栈插入新元素又称作进栈.入栈或压栈 ...

  7. linux heap堆分配

    heap堆分配在用户层面:malloc函数用于heap内存分配 void* malloc(size_t size); 进程的虚拟内存地址布局: 对用户来说,主要关注的空间是User Space.将Us ...

  8. 如何给女朋友讲明白:Java 中 Stack(栈) 与 Heap(堆)

    背景 Java 中 Stack(栈) 与 Heap(堆) 是面试中被经常问到的一个话题. 有没有对 Java 中 Stack(栈) 与 Heap(堆) 烂熟于心的童鞋,请举手!!!(怎么没人举手-) ...

  9. Delphi 堆栈 [ heap(堆) 和 stack(栈) ]

    程序需要的内存空间分为 heap(堆) 和 stack(栈); heap(堆) 是自由存储区, stack(栈) 是自动存储区; 使用 heap 需要手动申请.手动释放, 使用 stack 是自动申请 ...

  10. 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型

    小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...

随机推荐

  1. 5、Maven-构建配置文件

    什么是构建配置文件? 配置文件是一组配置的集合,用来设置或者覆盖Maven构建的默认设置, 使用配置文件可以为不同的环境定制构建过程,例如Producation和Development环境. Prof ...

  2. netty(七)buffer源码学习2

    概述 文章主要介绍的是PoolArena,PoolChunk,PoolSubpage 三个类的源码 PoolArena PoolArena 是netty 的内存池实现类,通过预先申请一块大的空间,然后 ...

  3. Codeforces Round #601 (Div. 2)E(寻找质因子,DP)

    先分解质因数,对于当前a[i],假设当前的质因数为x,这个位置要满足能被k整除,有两个可能,要么是它向后一个转移x%k个,要么是后一个向它转移k-x%k个. 对于每一个a[i]满足后,因为只会对下一个 ...

  4. 使用ssh 初始化git一个空java工程

    1:进入git 目录 cd /home/git/repo/ 2:创建一个java工程名 mkdir qft-payment 3:进入工程 cd  qft-payment/ 4:初始化空工程 git - ...

  5. Computational Complexity of Fibonacci Sequence / 斐波那契数列的时空复杂度

    Fibonacci Sequence 维基百科 \(F(n) = F(n-1)+F(n-2)\),其中 \(F(0)=0, F(1)=1\),即该数列由 0 和 1 开始,之后的数字由相邻的前两项相加 ...

  6. PyQt5信号与槽详解

    1.信号与槽函数基础'''信号与槽函数基础,信号是一个事件,发射信号之后槽函数就会执行'''from PyQt5.QtWidgets import *import sys class signal(Q ...

  7. tkinter学习(3)scale尺度条和menu菜单

    1.scale学习(尺度条)1.1 代码: #第1步:导出模块 import tkinter as tk #第2步:定义窗口,及其标题.大小和位置 win = tk.Tk() win.title('s ...

  8. 使用YUM安装软件时提示PackageKit睡眠中解决方法!

    报错如图所示: 解决方法一:移除var/run/yum.pid文件 方法二:直接杀掉进程号 报错的时候会跟进程号 直接利用kill   -9  +进程号

  9. 对list集合的内容分组

    /** * 把list集合里的内容按照len大小分组 * @param list * @param len * @return */ private static List<List<St ...

  10. Cake ZOJ - 3537

    题目链接 本题也是区间dp三角剖分板子题,只不过加入了判断是否是凸包,计算顺序要用凸包顺序(凸包板) #include<bits/stdc++.h> using namespace std ...