【数据结构】通用的最小堆(最大堆)D-ary Heap
听说有一种最小(大)堆,不限于是完全二叉树,而是完全D叉树,名为D-ary Heap(http://en.wikipedia.org/wiki/D-ary_heap)。D可以是1,2,3,4,100,对于优先队列该有的功能都没有问题。
动手写一个D-ary Heap,应该不难。简单起见,不考虑像STL一样通过template传入Comp类,下面的实现要求T类型重载了operator <和operator >。
template<class T>
class DaryHeap
{
size_t D;
size_t size;
vector<T> a;
...
};
用vector容器存储数据,是因为在优先队列的插入、构建、删除操作需要RandomAccessIterator,而使用deque或其他STL容器都将影响性能。
为了节约点访问vector::size()函数的代价,用size_t size记录堆的大小。这也许没有必要,因为编译器可能对size()的调用做优化,而且访问size()的次数也并不多。
然后写堆的基本操作,即元素的上移下移。完全D叉树的性质和二叉树差不多,甚至可以推广到1叉树(数组)。
void up(size_t i)
{
while(i)
{
size_t p = (i-)/D;
if(a[p]>a[i])
{
swap(a[p], a[i]);
i = p;
}
else break;
}
}
void down(size_t i)
{
size_t ii;
size_t min = i*D+;
while(min<size)
{
for(ii=i*D+; ii<size; ii++)
if(a[min] > a[ii]) min = ii;
if(a[min]<a[i])
{
swap(a[min], a[i]);
i = min;
min = i*D+;
}
else break;
}
}
写好了这两个函数,堆的插入删除排序构建就都一样了:
DaryHeap(int _D=):size()
{
if(_D<) D=;
else D=_D;
}
size_t getsize(){return size;}
void push(T& x)
{
a.push_back(x);
up(size++);
}
T& top()
{
if(size)
return a[];
}
void pop()
{
if(size)
{
a[] = a[--size];
a.pop_back();
down();
}
}
最后测试:
main()
{
DaryHeap<int> h();
for(int i=; i>; i--)
{
h.push(i);
// h.print();
}
for(int i=; i>; i--)
{
cout <<h.top()<<ends;
h.pop(); }
}
D-ary Heap的定义是:
1 逻辑上是一个完全多叉树;
2 每个父节点有最多D个子节点;
3 子节点永远比父节点大(小),前提是节点具有可比性。
性质:
1 父节点=(子节点-1)/D;
2 子节点=父节点*D+i (i=1, 2, ..., D);
操作:
1 插入时将新插入元素放在最尾端,并与父节点交换位置直到比父节点大,即up操作。
2 从一个数组a构建成一个D-ary Heap,即需要每一个a[i](i>1)做如上的up操作。
3 删除一个节点时,将尾部的节点复制到待删除节点的位置,size-=1,然后将新复制节点从待删除节点开始向下移动,直到所有的子节点都比新复制节点大,down操作。至于怎么求子节点中最小的那个,要么去构建个局部的最小堆,要么就只好遍历咯。
4 排序:每一次将堆的根节点与尾节点a[size-1]交换,同时size-=1,再调整新根节点的位置(就是将堆首删除后拿到数组尾端。)
总的来说,和熟为人知的二叉树除了up和down有一点点不同,其他的一模一样。
【数据结构】通用的最小堆(最大堆)D-ary Heap的更多相关文章
- 502. IPO(最小堆+最大堆法 or 排序法)
题目: 链接:https://leetcode-cn.com/problems/ipo/submissions/ 假设 力扣(LeetCode)即将开始其 IPO.为了以更高的价格将股票卖给风险投资公 ...
- c++/java/python priority_que实现最大堆和最小堆
#include<iostream>#include<vector>#include<math.h>#include<string>#include&l ...
- 最大堆 最小堆 解决TOPK问题
堆:实质是一颗完全二叉树,最大堆的特点:父节点值均大于子节点:最小堆的父节点值均小于子节点: 一般使用连续内存存储堆内的值,因而可以根据当前节点的索引值推断子节点的索引值: 节点i的父节点为(i-1) ...
- Google 面试题:Java实现用最大堆和最小堆查找中位数 Find median with min heap and max heap in Java
Google面试题 股市上一个股票的价格从开市开始是不停的变化的,需要开发一个系统,给定一个股票,它能实时显示从开市到当前时间的这个股票的价格的中位数(中值). SOLUTION 1: 1.维持两个h ...
- Black Box--[优先队列 、最大堆最小堆的应用]
Description Our Black Box represents a primitive database. It can save an integer array and has a sp ...
- C++ multiset通过greater、less指定排序方式,实现最大堆、最小堆功能
STL中的set和multiset基于红黑树实现,默认排序为从小到大. 定义三个multiset实例,进行测试: multiset<int, greater<int>> gre ...
- PAT-1147(Heaps)最大堆和最小堆的判断+构建树
Heaps PAT-1147 #include<iostream> #include<cstring> #include<string> #include<a ...
- 数据结构之最小堆的实现C++版
完全二叉树之所以用数组的方式存在,在于他的一个特性 若子节点为i,则父节点为(i-1)/2,注意c++特性,该结果肯定是个整数. 若父节点为j,则子节点必为2*j+1;则在数组里面可以非常方便的通过下 ...
- Python3实现最小堆建堆算法
今天看Python CookBook中关于“求list中最大(最小)的N个元素”的内容,介绍了直接使用python的heapq模块的nlargest和nsmallest函数的解决方式,记得学习数据结构 ...
随机推荐
- N层电梯只停一层情况下,求所有人爬楼层数最少
一.题目: 石家庄铁道大学基础教学楼一共有四部电梯,每层都有人上下,电梯在每一层都停.信1201-1班张一东每层都停有点儿不耐烦.如果在上下课高峰时刻电梯从一层上行,但只允许停留在某一层.每个人选择自 ...
- Hbase之shell操作
一. 介绍 HBase是一个分布式的.面向列的 开源数据库,源于google的一篇论文<bigtable:一个结构化数据的分布式存储系统>.HBase是Google Bigtable的开源 ...
- linux iostat命令详解 磁盘操作监控工具
Linux系统中的 iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视. 它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况. ...
- PHP学习之路 (2)
我们如果坚持用windows做PHP开发,就会错误不断,所以,无论如何都要学习Linux的使用和安装.说实话<鸟哥的linux私房菜>是一本非常不错的书,但是如果你想照着书上面一步一步安装 ...
- jQuery学习笔记(2)
val() 当鼠标放上去的时候,文本消失,鼠标拿开,文本恢复 效果图: code as below: <html xmlns="http://www.w3.org/1999/xhtml ...
- scrapy爬虫框架入门教程
scrapy安装请参考:安装指南. 我们将使用开放目录项目(dmoz)作为抓取的例子. 这篇入门教程将引导你完成如下任务: 创建一个新的Scrapy项目 定义提取的Item 写一个Spider用来爬行 ...
- C 简单处理excel 转成 json
引言 工作中常需要处理excel转json问题. 希望这篇博文能简单描述这个问题.并提供一种解决思路.提升感悟. 今天我们处理的事就是为了把 xlsm => json. 一种方式是. 去 goo ...
- 1092. To Buy or Not to Buy (20)
Eva would like to make a string of beads with her favorite colors so she went to a small shop to buy ...
- DB2查看用户表与指定用户表表结构
1.在dos中查看用户表 1.1查看表 DB2 LIST TABLES FOR USER 1.2 查看表结构 DB2 describe table A 2.在DB2连接工具中(这里以SQLdbx为例子 ...
- [原创]PostgreSQL Plus Advanced Server监控工具PEM(二)
2.安装PEM Client 简单两条命令,开始PEM Client的安装. 我们在SUSE 11sp2上安装PEM Client 安装结束,运行PEM Client后可以看到如下的界面: 目前我们并 ...