My集合框架第六弹 左式堆
左式堆(Leftist Heaps)又称作最左堆、左倾堆。左式堆作为堆的一种,保留了堆的一些属性。
第1,左式堆仍然以二叉树的形式构建;
第2,左式堆的任意结点的值比其子树任意结点值均小(最小堆的特性)。但和一般的二叉堆不同,左式堆不再是一棵完全二叉树(Complete tree),而且是一棵极不平衡的树。
package com.wpr.collection; /**
* 左式堆:二叉堆缺点,首先,只能查找最小元素;其次,将两个堆合并的操作很麻烦
* 注意:所有支持有效合并的高级数据结构都需要使用链式数据结构
*
* 定义:零路径长(null path length)npl表示从节点X到一个不具有两个儿子的节点的最短路径的长
*
* @author wpr
*
*/
public class LeftHeap<AnyType extends Comparable<? super AnyType>> { private Node<AnyType> root; public LeftHeap() {
root = null;
}
private static class Node<AnyType> {
AnyType element;
Node<AnyType> left;
Node<AnyType> right;
int npl;
public Node(AnyType element) {
this(element,null,null);
}
public Node(AnyType element, Node<AnyType> left, Node<AnyType> right) {
this.element = element;
this.left = left;
this.right = right;
this.npl =0 ;
}
}
/**
* @param x
*/
public void merge(LeftHeap<AnyType> x){
if(this == x)
return ; root = merge(root,x.root);
}
/**
* 插入一个新元素
* @param x
*/
public void insert(AnyType x){
root = merge(new Node<AnyType>(x),root);
}
/**
* 删除最小元素
* @return
*/
public AnyType deleteMin(){
if(root == null)
return null; AnyType item = root.element;
root = merge(root.left,root.right); return item;
}
/**
* 将h1和h2两个堆合并,返回根节点(递归的方式实现)
* @param h1
* @param h2
* @return
*/
private Node<AnyType> merge(Node<AnyType> h1, Node<AnyType> h2) {
if(h1 == null)
return h2;
if(h2 == null)
return h1;
if(h1.element.compareTo(h2.element)<0){
//h1<h2
return merge1(h1,h2);
}else{
return merge1(h2,h1);
}
}
/**
* 将较小的堆min和较大的堆max合并,返回根节点
* @param min 较小的堆,不为null
* @param max 较大的堆,不为null
* @return
*/
private Node<AnyType> merge1(Node<AnyType> min, Node<AnyType> max) {
if(min.left==null) //min是一个叶子节点
min.left = max;
else{
min.right = merge(min.right,max); //较小堆的右子堆和较大堆合并
if(min.left.npl<min.right.npl){
swapChildren(min);
}
min.npl = min.right.npl+1;
}
return min;
}
/**
* 交换节点的左右子堆
* @param min
*/
private void swapChildren(Node<AnyType> min) {
Node temp = min.left;
min.left = min.right;
min.right = temp;
}
/**
* 非递归的方式来写一下
* @param min
* @param max
* @return
*/
/* private Node<AnyType> merge2(Node<AnyType> h1, Node<AnyType> h2) {
while(h1!=null && h2!=null){ }
}*/
public static void main(String[] args) {
LeftHeap<Integer> heap = new LeftHeap<>();
for(int i=0;i<10;i++)
heap.insert(i);
print(heap);
} public static void print(LeftHeap h){
while(h.root!=null){
System.out.println(h.deleteMin());
}
}
}
My集合框架第六弹 左式堆的更多相关文章
- Heap:左式堆的应用例(任意序列变单调性最小价值)
首先来说一下什么是左式堆: A:左式堆是专门用来解优先队列合并的麻烦(任意二叉堆的合并都必须重新合并,O(N)的时间). 左式堆的性质: 1.定义零路经长:节点从没有两个两个儿子节点的路经长,把NUL ...
- 结构之美——优先队列基本结构(四)——二叉堆、d堆、左式堆、斜堆
实现优先队列结构主要是通过堆完成,主要有:二叉堆.d堆.左式堆.斜堆.二项堆.斐波那契堆.pairing 堆等. 1. 二叉堆 1.1. 定义 完全二叉树,根最小. 存储时使用层序. 1.2. 操作 ...
- My集合框架第五弹 最小堆
二叉堆(以最小堆为例),其具有结构性质和堆序性质结构性质: 堆是一棵完全的二叉树,一颗高为h的完全二叉树有2^h到2^h-1个节点,高度为log N 而且该结构可以很容易的使用数 ...
- My集合框架第三弹 AVL树
旋转操作: 由于任意一个结点最多只有两个儿子,所以当高度不平衡时,只可能是以下四种情况造成的: 1. 对该结点的左儿子的左子树进行了一次插入. 2. 对该结点的左儿子的右子树进行了一次插入. 3. 对 ...
- Java集合框架(六)—— Collections工具类
操作集合的工具类Collections Java提供了一个操作Set.List和Map等集合的工具类:Collections,该工具类里提供了大量方法对集合元素进行排序.查询和修改等操作,还提供了将集 ...
- java 集合框架(十六)Map
一.概述 Map是一个包含键值对的集合,一个map不能有重复的键(key),而且每个键至多只能对应一个值.Map同Collection一样,它的所有通用实现都会提供一个转换器构造函数,接收一个Map类 ...
- My集合框架第四弹 HashTable(链表解决冲突)
package com.wpr.collection; import java.util.LinkedList; import java.util.List; public class HashTab ...
- 第十章 优先级队列 (xa3)左式堆:插入与删除
- 第十章 优先级队列 (xa2)左式堆:合并
随机推荐
- 如何添加真机调试的iOS设备
注意点: 有时需要同意协议什么的,很多时候刷新出来都是白屏,解决办法: 对于不能确认新协议的问题,我发现了一个解决方法:登陆后,直接在浏览器的地址框访问:https://developer.apple ...
- Sqlserver高级查询
1.查询表结构 --查询表结构(字段名.字段类型.字段长度.能否为空) SELECT syscolumns.name,systypes.name, syscolumns.length ,syscolu ...
- django - raw sql - 注意点!
现在的自己已经不怕mysql,已经熟悉了sql “搜索优化专家有时候都无法顾全所有,更何况ORM” 两种方法执行 sql原生语句 tablename.objects.raw() - 这样的语句,只能执 ...
- Linux用户(组)管理
在linux中系统中,它并不认识帐号名称.它认识的是我们的帐号ID,帐号ID保存在/etc/passwd文件中.我们在登录linux主机时,在输入完帐号和密码时,linux会先查找/etc/passw ...
- 安卓 Dialogs(对话框)
转载自:http://www.apkbus.com/home.php?mod=space&uid=679028&do=blog&id=61197 对话框是一个小的窗口用以提示用 ...
- Servlet中response.sendRedirect()跳转时不能设置target的解决办法
一般使用Struts2的拦截器(或者是filter)验证是否登录的时候,如果用户没有登录则会跳转到登录的页面.这时候一般可以在拦截器或者filter中用response.sendRedirect(). ...
- Garlands
题意: n个数分成m段,每段偶数个数,最小化和最大段的半个区间的数字和. 分析: 先想到了二分,dp求能分成的最小段数. #include <map> #include <set&g ...
- loadrunner之C语言编程
一.常量定义 #define COUNT 100 //定义全局常量#define SALARY 4000 Action(){ int total; total = C ...
- LoadRunner--内存指标介绍
Threads——线程数当前全部线程数============================================ Available MBytes——物理内存的可用数指计算机上可用于运行 ...
- LR录制脚本IE不能打开解决方法
运行环境:win7 64位 解决方法:1.卸载IE11 2.计算机——属性——高级系统设置——性能里的设置——数据执行保护——选择“为除下列选定程序之外的所有程序和服务启用”——添加IE浏览器和VUG ...