左式堆(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());
}
}
}
05-11 00:43