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());
		}
	}
}

 

posted @ 2015-03-12 17:14  卡卡西sir  阅读(192)  评论(0编辑  收藏  举报