优先队列之左式堆(JAVA实现)
来源:互联网 发布:部落实验室升级数据 编辑:程序博客网 时间:2024/06/02 03:21
一、定义:
1.零路径长度:某节点的零路径长度为该节点到没有两个儿子的节点最短距离。
2.左式堆性质:
- 父节点属性值小于子节点属性值;
- 堆中的任何节点,其左儿子的零路径长>=右儿子的零路径长的二叉树。
- 任一结点的零路径长比他的诸儿子结点的零路径长的最小值多1。
二、实现思路:
1.合并:
左式堆的合并操作基于递归实现,算法思路如下:
- 若有一棵树是空树,则返回另一棵树;否则将根节点较大的堆与根节点较小的堆的右子树合并。
- 使形成的新堆作为较小堆的右子树。
- 如果违反了左式堆的特性,交换两个子树的位置。
- 更新npl(零路径长度)。
2.插入
将需要插入的节点当做一棵左式堆树,进行合并。
3.删除最小值
删除根节点,将形成的两个堆合并
三、代码实现
public class LeftistHeap<T extends Comparable> { /** * Created by Administrator on 2017/6/13. */ class Node<T> { T element; Node<T> left;//左儿子 Node<T> right;//右儿子 int npl;//零路径长 Node(T element) { this(element, null, null); } Node(T element, Node<T> left, Node<T> right) { this.element = element; this.left = left; this.right = right; npl = 0; } } private Node<T> root; /** * 构造方法 */ public LeftistHeap() { root = null; } /** * 合并堆 * * @param rhs 另一个左式堆 */ public void merge(LeftistHeap<T> rhs) { if (this == rhs) { return; } root = merge(root, rhs.root); rhs.root = null; } public void insert(T x) { root = merge(root, new Node(x)); } /** * 找出最小元素 * * @return */ public T findmin() { if(isEmpty()){ System.out.println("该左式堆为空"); } return root.element; } /** * 删除最小元素 * * @return */ public T deleteMin() { if (isEmpty()) { System.out.println("该左式堆为空"); } T minElement = root.element; root=merge(root.left, root.right); return minElement; } /** * 是否为空 * * @return */ public boolean isEmpty() { return root == null; } /** * 置空 */ public void makeEmpty() { this.root = null; } /** * 合并两个左式堆(判断过程,真正合并过程由merge1操作) * * @param h1 * @param h2 * @return */ private Node<T> merge(Node<T> h1, Node<T> h2) { if (h1 == null) return h2; if (h2 == null) return h1; if (h1.element.compareTo(h2.element) > 0) return merge1(h2, h1); else return merge1(h1, h2); } /** * 合并两个左式堆的真正操作 h1的元素小于h2(即h2与h1的右子堆合并) * * @param h1 * @param h2 * @return */ private Node<T> merge1(Node<T> h1, Node<T> h2) { if (h1.left == null) {//h1为单节点 h1.left = h2; } else {//h1不是单节点 h1.right = merge(h1.right, h2); if (h1.right.npl > h1.left.npl) {//比较零路径长,确保左式堆性质不被破坏 swapChildren(h1); } h1.npl = h1.right.npl + 1;//零路径长为右儿子的零路径长+1 } return h1; } /** * 交换左右儿子 * * @param t * @return */ private void swapChildren(Node<T> t) { Node<T> temp = t.right; t.right = t.left; t.left = temp; } private void print(Node t){ if(t==null) return; print(t.left); System.out.println(t.element+":"+t.npl); print(t.right); } public static void main(String[] args) { int numItems = 100; LeftistHeap<Integer> h = new LeftistHeap<>( ); LeftistHeap<Integer> h1 = new LeftistHeap<>( ); int i = 37; for( i = 37; i != 0; i = ( i + 37 ) % numItems ) if( i % 2 == 0 ) h1.insert( i ); else h.insert( i ); h.merge( h1 ); for( i = 1; i < numItems; i++ ) if( h.deleteMin( ) != i ) System.out.println( "Oops! " + i ); }}
阅读全文
0 0
- 优先队列之左式堆(JAVA实现)
- java 之堆实现优先队列
- 优先队列之二叉堆(JAVA实现)
- JAVA队列之优先队列
- JAVA队列之优先队列
- 优先队列之二项队列(JAVA实现)
- 优先队列之左式堆
- 数据结构之优先队列--二叉堆(Java实现)
- 数据结构之优先队列--二叉堆(Java实现)
- 基于优先队列PriorityQueue的Dijstra算法之Java实现
- 看图说话之左式堆(优先队列)——原理解析及java实现
- 数据结构实现之最小索引优先队列
- 数据结构实现之最大索引优先队列
- 【数据结构】之用堆实现优先队列
- java使用堆结构实现优先队列
- 用java实现优先级别队列
- 数据结构-堆实现优先队列(java)
- 优先队列及java实现和用法
- Java双括号初始化
- java中的args参数
- 最新版本的LAMP搭建
- 51nod 1245 Binomial Coefficients Revenge
- MongoDB常用操作(二)
- 优先队列之左式堆(JAVA实现)
- LeetCode 523. Continuous Subarray Sum
- 常用网址导航记录
- 写作建议
- Python :顺时针打印矩阵
- 51nod1577 异或凑数
- 把数字转换成中文
- 数据库外连接(左、右、全)、内连接
- Mysql数据乱码完美解答