ADT - heap(堆)

二叉堆:

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

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

#include "stdafx.h"
#include <iostream>
#include <vector>

#define LeftChild(i) (2*(i) + 1)
#define RightChild(i) (2*((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),空间复杂度O(1);

  down_build是形如‘下滤’的过程,时间复杂度为O(n),空间复杂度O(1),有点不可思议,不过这里《数据结构与算法分析》书中说下滤建堆也是O(n),但知乎上有证明下滤是O(nlgn) = = 难道是我看错了?其实我也觉得自顶向下建堆的复杂度为O(nlgn))。

 左式堆:

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

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

  参考资料:

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

    2.知乎相关问题

原文地址:https://www.cnblogs.com/darkchii/p/8542145.html

时间: 2024-08-30 15:41:17

ADT - heap(堆)的相关文章

Stack栈 Heap堆

Stack(栈) 栈(stack) 又名堆栈,它是一种运算受限的线性表.其限制是仅允许在表的一端进行插入和删除运算.这一端被称为栈顶,相对地,把另一端称为栈底.向一个栈插入新元素又称作进栈.入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素:从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素. 在计算机科学中是限定仅在表尾进行插入或删除操作的线性表.栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数

java 中的内存分为四个部分:stack(栈),heap(堆),data segment

http://www.qdmm.com/BookReader/113167,54166719.aspx http://www.qdmm.com/BookReader/113167,54166867.aspx http://www.qdmm.com/BookReader/113167,54166868.aspx http://www.qdmm.com/BookReader/113167,54166869.aspx http://www.qdmm.com/BookReader/113167,5416

linux heap堆分配

heap堆分配在用户层面:malloc函数用于heap内存分配 void* malloc(size_t size); 进程的虚拟内存地址布局: 对用户来说,主要关注的空间是User Space.将User Space放大后,可以看到里面主要分为如下几段: Code:这是整个用户空间的最低地址部分,存放的是指令(也就是程序所编译成的可执行机器码) Data:这里存放的是初始化过的全局变量 BSS:这里存放的是未初始化的全局变量 Heap:堆,这是我们本文重点关注的地方,堆自低地址向高地址增长,后面

Java Stack栈和Heap堆的区别

首先分清楚Stack,Heap的中文翻译:Stack—栈,Heap—堆. 在中文里,Stack可以翻译为“堆栈”,所以我直接查找了计算机术语里面堆和栈开头的词语: 堆存储: heapstorage 堆存储分配: heapstorage allocation 堆存储管理: heap storage management 栈编址: stack addressing 栈变换:stack transformation 栈存储器:stack memory 栈单元: stack cell 接着,总结在Jav

heap(堆)和stack(栈)的区别

heap是堆,stack是栈 stack的空间由操作系统自动分配/释放,heap上的空间手动分配/释放. stack空间有限,heap是很大的自由存储区 C中的malloc函数分配的内存空间即在heap上,C++中对应的是new操作符. 程序在编译期对变量和函数分配内存都是在stack(栈)上进行,且程序运行过程中的函数调用时参数的传递也在栈上进行.

Heap堆

#pragma once#include<iostream>using namespace std;#include<vector> template<class T>    //仿函数struct Less{    bool operator()(const T&l, const T&r)  //重载括号    {        return l < r;    }}; template<class T>struct Greater{

STL之heap 堆

STL中与堆相关的4个函数--建立堆make_heap(),在堆中添加数据push_heap(),在堆中删除数据pop_heap()和堆排序sort_heap(): 头文件 #include <algorithm> 下面的_First与_Last为可以随机访问的迭代器(指针),_Comp为比较函数(仿函数),其规则--如果函数的第一个参数小于第二个参数应返回true,否则返回false. 建立堆 make_heap(_First, _Last, _Comp) 默认是建立最大堆的.对int类型,

heap 堆

通过优先队列可以构造堆,堆是一种实用的数据结构.尽管Python中没有独立的堆类型,但是包含了一些对操作函数的模块,这个模块叫heapq,主要的操作包含如下几个: heappush(heap,x):x元素插入堆 heappop(heap):弹出对中最小元素 heapify(heap):将heap属性强制应用到任意一个列表 hrapreplace(heap,x):将heap中最小元素弹出,同时x元素入堆 hlargest(n,iter):返回iter中第n大的元素 hsmallest(n,iter

[数据结构] 2.7 Heap 堆

* 注: 本文/本系列谢绝转载,如有转载,本人有权利追究相应责任. 1.堆是什么? (如图所示是一个小堆) 1)堆是一颗完全二叉树,它的最后一层不是满的,其他每一层都是满的,最后一层从左到右也没有空隙. 简单的说?  完全二叉树也就是没有缝隙的二叉树. 2)堆常常通过数组实现,因为 父子节点直接的关系直接可以通过数组的索引换算 parent(i) = i/2 left child(i) = 2*i + 1 right child(i) = 2*i + 2 3)对于最大堆来说,每个节点的值都不大于