这里的堆不是java中内存分配的堆。只是一种数据结构。
堆是二叉满树,满足条件:父节点的键值大于两个子节点的键值,这不同于二叉搜索树(见Tree),堆对于实现优先级队列是一种好的方式,相对于利用数组的优先级队列
,利用链表的优先级队列
来说,其插入与删除的效率都是O(log n)
此堆的实现使选择数组作为内部数据结构,使得此堆能容纳的数据有限,但找到最下一层的作右子节点比交方便。用数组存储树时,求当前节点的父节点和左右子节点的公式如下:假设当前节点坐标为x:
父节点:(x-1)/2
左子节点:2 * x + 1
右子节点:2 * x + 2
API如下:
Heap:构造并指定需要的空间大小
add:添加数据
remove:删除最大的数据
isEmpty:堆是否为空
其余的都是辅助方法,其中最有用的是:
trickleDown:将指定位置的节点,按照堆的约定规则向下调整到合适的位置
trickleUp:将指定位置的节点,按照堆的约定规则向上调整到合适的位置
print:测试辅助方法
Node为辅助类,表示要存取的键值与数值。
Heap.main:提供简短的测试。
class Node {//表示装数据的节点
private int key; //排序的关键字
private Object value; //数据
Node(int key, Object value) {
this.key = key;
this.value = value;
}
int key() { return key; }
Object value() { return value; }
}
class Heap {
private Node[] array; //序排序的数组
private int pos; //当前有效数据的个数
Heap(int size) {
array = new Node[size];
}
void add(Node node) { //将新数据插入数组
assert pos < array.length;
array[pos] = node; //将新数据插入数组的最后(堆的最后一个元素之后)
trickleUp(pos++); //将数据提升致恰当的位置
}
Node remove() { //删除堆的顶
Node result = array[0]; //将最后一个元素提至堆定
array[0] = array[--pos]; //将堆顶下降为恰当位置
trickleDown(0);
return result;
}
boolean isEmpty() {
return pos == 0;
}
private void trickleUp(int index) {
Node bottom = array[index]; //暂存要提升的数据
int parent = getParent(index); //得到父节点的位置
//如果节点存在,且父节点的关键字的值小于要提升数据的关键字
while (index > 0 && array[parent].key() < bottom.key()) {
array[index] = array[parent]; //将父节点下降,留出空位
index = parent; //重复以上过程
parent = getParent(index);
}
array[index] = bottom; //将暂存的数据放入恰当的位置
}
private void trickleDown(int index) {
Node top = array[index]; //存放要下降的数据
int left = getLeft(index); //得到左子的位置
int right = getRight(index); //得到右子的位置
int current; //当前可能要下降的位置
if(left < pos && right < pos) //左右子节点有效,当前的位置设置为左右子节点中小的那个
current = array[left].key() > array[right].key() ? left : right;
else if (left < pos) current = left; //如果左子节点有效,则当前位置设置为左子节点
else current = -1; //没有可以下降的位置
while(current != -1 && array[current].key() > top.key()) { /当前节点有效且大于要下降的数据
array[index] = array[current]; //将当前节点向上提升,留出空位
index = current; //重复以上过程
left = getLeft(index);
right = getRight(index);
if(left < pos && right < pos)
current = array[left].key() > array[right].key() ? left : right;
else if (left < pos) current = left;
else current = -1;
}
array[index] = top; //将暂存的数据放入恰当的位置
}
private int getParent(int index) {
return (index-1)/2;
}
private int getLeft(int index) {
return 2 * index + 1;
}
private int getRight(int index) {
return 2 * index + 2;
}
void print() {
for(int i=0; i<pos; i++) {
System.out.print(array[i].key() + ",");
}
System.out.println();
}
public static void main(String[] args) {
Heap heap = new Heap(100);
heap.add(new Node(50,"hello"));
heap.add(new Node(20,"jason"));
heap.add(new Node(60,"peter"));
heap.add(new Node(50,"orange"));
heap.add(new Node(30,"temp"));
heap.add(new Node(40,"hello"));
heap.add(new Node(90,"jason"));
heap.add(new Node(10,"peter"));
heap.add(new Node(5,"orange"));
heap.add(new Node(300,"temp"));
heap.print();
while(!heap.isEmpty()) {
Node node = heap.remove();
System.out.println(node.key() + " = " + node.value());
}
}
}
分享到:
相关推荐
Heap堆解题套路【LeetCode刷题套路教程6】
JVM堆分析,Java VM堆分析(节选)。 JProbe 是目前最好的Java性能优化工具之一,在全球有最多的用户。 本文档不但介绍了JProbe的在解决内存问题方面的功能和使用,同时还介绍了必要的Java内存管理的背景知识,深入...
最近在学习STL的源代码,看到这么多优秀的代码,心里痒痒的,于是自己实现了一遍,当然,有自己的特色,都是模块函数,稍稍用了一些traits特性。相互学习,呵呵
非常简单的一个最大堆的类,经过测试可以运行,希望可以对新手有所帮助。
用C++和模板实现最大堆,可用于简单排序操作
垃圾收集(GC)是指JVM释放Java堆中不再使用的对象所占用...为了获取理想的Heap堆大小,需要使用-verbosegc参数(Sun jdk: -Xloggc:)以打开详细的GC输出。分析GC的频度和时间,结合应用最大负载所需内存情况,得出堆的大小。
2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。3、全局区(静态区)(static)—全局变量和静态变量的存储是放在一块...
15年7月最新版的工具Heap Analzer V4。 分析java内存堆快照的利器,拥有直觉性的判断溢出对象是什么,一目了然。支持上下左右键,免去鼠标点击的痛苦。 对象显示也比较详细,数量,大小都包含,支持对象树的复制。
通过heapdump工具分析服务器堆分配问题
java虚拟机OutOfMemoryError:Java heap space堆dump文件,可以直接用来分析。
堆溢出攻击教程(heap overflow attack)
eager binomial heaps python实现。使用双向链表,make_heap, insert, merge, find_min, extractMin.
在clion中对fibonacci heap的完全实现,亲测有效。
java中堆(heap)和堆栈(stack)有什么区别
c语言实现 小根堆heap,每次pop的时候都是最小值。整个值以数组形式储存!
二(三续)、Dijkstra 算法+Heap 堆的完整c 实现源码 三、dynamic programming 四、BFS 和DFS 优先搜索算法 五、红黑树算法的实现与剖析 五(续)、教你透彻了解红黑树 六、教你从头到尾彻底理解KMP 算法 七、遗传...
Visual C++ 小内存堆(Small Block Heap)问题
在一些平台上,在有些情况下,javacore也被称为javadump,它包含jvm和应用程序相关的在特定时刻的一些诊断信息,如操作系统,应用程序环境,线程,native stack本地堆,锁,和内存的信息。在生成heapdump文件的时候...
ibm-java-堆内存分析工具-heapanalyzer
1.3 Heap堆内存模型 第三节:定位垃圾对象的依据 1.1 引用计数法 1.2 可达性算法 第四节:垃圾回收算法 1.1标记清除算法 1.2复制算法 1.3 标记整理(标记压缩)算法 第五节:垃圾回收器 1.1Serial/Serial Old...