• 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());
    		}
    	}
    }
    
  • 相关阅读:
    c# asp.net 鼠标改变控件坐标位置,更改控件坐标,注册表保存读取,打印,查找局域网内打印机等等收集
    jquery,extjs中的extend用法小结
    JavaScript创建Map对象(转)
    ExtJS与jQuery的一点细节上的对比
    jQuery 的原型关系图,整体把握jQuery
    github网站介绍、并使用git命令管理github(详细描述)
    1.移植3.4内核-分析内核启动过程,重新分区,烧写jffs2文件系统
    6.移植uboot-支持yaffs烧写,打补丁
    5.移植uboot-设置默认环境变量,裁剪,并分区
    4.移植uboot-使uboot支持DM9000网卡
  • 原文地址:https://www.cnblogs.com/kakaxisir/p/4332965.html
Copyright © 2020-2023  润新知