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)左式堆:合并
随机推荐
- 解读 Windows Azure 存储服务的账单 – 带宽、事务数量,以及容量
经常有人询问我们,如何估算 Windows Azure 存储服务的成本,以便了解如何更好地构建一个经济有效的应用程序.本文我们将从带宽.事务数量,以及容量这三种存储成本的角度探讨这一问题. 在使用 W ...
- order by多个字段对索引的影响
某前台sql语句,简化后如下SELECT products_name,products_viewed FROM `products_description` ORDER BY products_vie ...
- log4j配置文件详细解释
web.xml中配置启动log4j的配置 <!-- webAppRootKey进行配置,这里主要是让log能将日志写到对应项目根目录下 --> <!-- 定义以后,在Web Cont ...
- OpenGL学习之路(三)
1 引子 这些天公司一次次的软件发布节点忙的博主不可开交,另外还有其它的一些事也占用了很多时间.现在坐在电脑前,在很安静的环境下,与大家分享自己的OpenGL学习笔记和理解心得,感到格外舒服.这让我回 ...
- IOS公司开发者账号申请详细教程
谈到苹果开发者账号,我们需要区分一下个人账号.公司账号和企业账号这三种,还有一种是教育账号,这个就不多说了. 个人账号:个人申请用于开发苹果app所使用的账号,仅限于个人使用,申请比较容易,$99. ...
- div 绝对布局居中
#loginbg{ position:absolute; height:200px; width:400px; margin:-100px 0px 0px -200px; top: 50%; left ...
- vmware 连网
Nat 这 种方式下,虚拟机的网卡连接到宿主的 VMnet8 上.此时系统的 VMWare NAT Service 服务就充当了路由器的作用,负责将虚拟机发到 VMnet8 的包进行地址转换之后发到实 ...
- C# 中对WinForm窗体中的控件快速设置TableIndex次序
点击“视图”--“Tab键顺序”,然后便可设置.
- 浏览器的DNS缓存
通过设置hosts文件可以强制指定域名对应的IP,当修改hosts文件,想要浏览器生效,最直接的方法关闭浏览器后重新开启:如果不想重启浏览器,只需要清空浏览器的DNS缓存即可.清空DNS缓存在chro ...
- Golang 绘图技术(image/draw包介绍)
image/draw 包仅仅定义了一个操作:通过可选的蒙版图(mask image),把一个原始图片绘制到目标图片上,这个操作是出奇的灵活,可以优雅和高效的执行很多常见的图像处理任务. 1 ...