树堆TreapMap 实现

来源:互联网 发布:手机记牌器软件 编辑:程序博客网 时间:2024/05/23 14:16

测试结果居然比红黑树,AVL都块。

import java.util.Random;public class TreapMap<Key extends Comparable <Key>, Value> {private class Node {Key key;Value value;Node left, right;int ht, sz, priority;Node(Key k, Value v) {this.key = k;this.value = v;this.ht = 1;this.sz = 1;this.priority = random.nextInt();}}private Node root;private Random random = new Random();private int height(Node root) {if (root == null) return 0;return root.ht;}private int size(Node root) {if (root == null) return 0;return root.sz;}private Value get(Node root, Key key) {if (root == null) return null;int cmp = key.compareTo(root.key);if (cmp == 0) return root.value;if (cmp < 0) return get(root.left, key);return get(root.right, key);}public Value get(Key key) { return get(root, key);}private void update(Node root) {root.sz = size(root.left) + size(root.right) + 1;root.ht = Math.max(height(root.left), height(root.right)) + 1;}private Node rotateRight(Node root) {Node l = root.left;root.left = l.right;update(root);l.right = root;update(l);return l;}private Node rotateLeft(Node root) {Node r = root.right;root.right = r.left;update(root);r.left = root;update(r);return r;}private Node maintain(Node root) {if (root.left != null && root.left.priority > root.priority)root = rotateRight(root);else if (root.right != null && root.right.priority > root.priority)root = rotateLeft(root);update(root);return root;}private Node put(Node root, Key key, Value value) {if (root == null) return new Node(key, value);if (key.compareTo(root.key) < 0) root.left = put(root.left, key, value);else if (key.compareTo(root.key) > 0) root.right = put(root.right, key, value);else root.value = value;return maintain(root);}public void put(Key key, Value value) {root = put(root, key, value);}private Node min(Node root) {if (root.left == null) return root;return min(root.left);}private Node remove(Node root, Key key) {if (root == null) return null;if (key.compareTo(root.key) < 0) {root.left = remove(root.left, key);}else if (key.compareTo(root.key) > 0) {root.right = remove(root.right, key);}else {if (root.left == null) return root.right;else if (root.right == null) return  root.left;else {Node successor = min(root.right);Key tempKey = root.key;root.key = successor.key;root.value = successor.value;successor.key = tempKey;root.right = remove(root.right, tempKey);}}return maintain(root);}public void remove(Key key) {root = remove(root, key);}private int rank(Node root, Key key) {if (root == null) return 0;if (key.compareTo(root.key) == 0) return size(root.left);if (key.compareTo(root.key) < 0) return rank(root.left, key);return size(root.left) + 1 + rank(root.right, key);}public int rank(Key key) {return rank(root, key);}private Node select(Node root, int rank) {if (root == null) return null;if (rank == size(root.left)) return root;if (rank < size(root.left)) return select(root.left, rank);return select(root.right, rank - size(root.left) - 1);}public Key select(int rank) {Node x = select(root, rank);if (x == null) return null;return x.key;}}

平衡树的研究告一段落(就差Splay Tree,这个不算平衡树)。RBT,AVL,SBT,Treap 区别只是节点信息和 maintain函数(保证满足特定的性质)。从面向对象的角度,可以以一个普通BST作为基类,所有的读操作(get, floor, ceiling, rank, select, range query) 放在普通BST里;rotate,insert 和 delete(除了RBT)也可以。这里有一个方法模板设计模式,插入和删除的主体步骤是一样的,具体的平衡树类只是最后的maintain步骤不同,只需要扩展Node 和 重写maintain函数。



0 0
原创粉丝点击