1, Binary lookup tree
- Each node contains a Comparable key (and related values). The key of each node is greater than that of any node in the left subtree and less than that of any node in the right subtree
- Each node contains a key, a value, a left link and a right link, and a node counter. The left link points to a binary search tree composed of all keys smaller than the node, and the right link points to a binary search tree composed of all keys larger than the node.
- Search: starting from the root node, the search process in each node will recursively expand in one of its child nodes. For the hit search, the path ends at the node containing the searched key. For missed lookups, the end of the path is an empty connection
- Insert: if the tree is empty, a new node containing key value pairs is returned; If the searched key is smaller than the key of the root node, continue to insert the key in the left subtree, otherwise insert the key in the right subtree
- Round down or round up: if the given key value is less than the key of the root node of the binary search tree, the maximum key floor(key) less than or equal to the key must be in the left subtree of the root node; If the given key value is greater than the key of the root node of the binary lookup tree, only when the right subtree of the root node exists and the node less than or equal to the key is, the maximum key floor(key) less than or equal to the key will appear in the right subtree, otherwise the root node is the maximum key less than or equal to the key.
- Ranking: if the given key is equal to the key of the root node, return the total number of nodes in the left subtree; If the given key is less than the root node, return the ranking of the key in the left subtree; If the given key is greater than the root node, return T + 1 (root node) plus its ranking in the right subtree
- Select: if the number of nodes t of the left subtree is greater than k, continue to recursively find the key ranked K in the left subtree; If equal, return the key of the root node; If t is less than k, recursively find the key ranked (k-t-1) in the right subtree.
- Delete minimum key: if the deleted node has only one node, the child node of the node will be on the top; If there are two nodes, find the smallest node of the right node and take the node as the replacement node. The right node of the node is the right subtree after deleting the node, and the left node is the left subtree of the original deleted node.
- Range search: in the middle order traversal mode, print all keys of the left subtree of the root node, then print the root node and print the right subtree
package Binary sort tree; import java.util.LinkedList; import java.util.Queue; public class BST<Key extends Comparable<Key>, Value> { private Node root; private class Node { private Key key; private Value val; private Node left, right; private int N; public Node(Key key, Value val, int n) { this.key = key; this.val = val; N = n; } } public int size() { return size(root); } public int size(Node root) { if (root == null) return 0; else return root.N; } public Value get(Key key) { return get(root, key); } public Value get(Node root, Key key) { if (root == null) return null; int vmp = key.compareTo(root.key); if (vmp < 0) return get(root.left, key); else if (vmp > 0) return get(root.right, key); else return root.val; } public void put(Key key, Value val) { root = put(root, key, val); } public Node put(Node root, Key key, Value value) { if (root == null) return new Node(key, value, 1); int cmp = key.compareTo(root.key); if (cmp < 0) root.left = put(root.left, key, value); else if (cmp > 0) root.right = put(root.right, key, value); else root.val = value; root.N = size(root.left) + size(root.right) + 1; return root; } public Key min() { return min(root).key; } private Node min(Node root) { if (root.left == null) return root; return min(root.left); } public Key floor(Key key) { Node x = floor(root, key); if (x == null) return null; return x.key; } //Round down, less than or equal to key Maximum value of private Node floor(Node x, Key key) { if (x == null) return null; int cmp = key.compareTo(x.key); if (cmp == 0) return x; if (cmp < 0) return floor(x.left, key); Node t = floor(x.right, key); if (t != null) return t; else return x; } public Key max() { return max(root).key; } private Node max(Node x) { if (x.right == null) return x; return max(x.right); } public Key ceiling(Key key) { return ceiling(root, key).key; } private Node ceiling(Node x, Key key) { if (x == null) return null; int cmp = key.compareTo(x.key); if (cmp == 0) return x; else if (cmp > 0) return ceiling(x.right, key); Node t = floor(x.left, key); if (t != null) return t; else return x; } public Key select(int k) { return select(root, k).key; } //Select and find the ranking as K Node of private Node select(Node x, int k) { if (x == null) return null; int t = size(x.left); if (t > k) return select(x.left, k); else if (t < k) return select(x.right, k - t - 1); else return x; } public int rank(Key key) { return rank(key, root); } //Returns the ranking of a given key private int rank(Key key, Node x) { if (x == null) return 0; int cmp = key.compareTo(x.key); if (cmp < 0) return rank(key, x.left); else if (cmp > 0) return 1 + size(x.left) + rank(key, x.right); else return size(x.left); } //Delete max key public void deleteMax() { } // Delete minimum build public void deleteMin() { root = deleteMin(root); } private Node deleteMin(Node x) { if (x.left == null) return x.right; x.left = deleteMin(x.left); x.N = size(x.left) + size(x.right) + 1; return x; } public void delete(Key key) { root = delete(root, key); } private Node delete(Node x, Key key) { if (x == null) return null; int cmp = key.compareTo(x.key); if (cmp < 0) x.left = delete(x.left, key); else if (cmp > 0) x.right = delete(x.right, key); else { if (x.right == null) return x.left; if (x.left == null) return x.right; Node t = x; x = min(t.right); x.right = deleteMin(t.right); x.left = t.left; } x.N = size(x.left) + size(x.right) + 1; return x; } // Search range public Iterable<Key> keys(){ return keys(min(),max()); } private Iterable<Key> keys(Key lo,Key hi){ Queue<Key> queue=new LinkedList<>(); keys(root,queue,lo,hi); return queue; } private void keys(Node x,Queue<Key> queue,Key lo,Key hi){ if(x==null)return; int cmplo=lo.compareTo(x.key); int cmphi=hi.compareTo(x.key); if(cmplo<0) keys(x.left,queue,lo,hi); if(cmplo<=0&&cmphi>=0) queue.offer(x.key); if(cmphi>0) keys(x.right,queue,lo,hi); } }
2, Balanced lookup tree
- A 2-3 lookup tree is either an empty tree or consists of the following nodes:
- 2-node: contains a key (and its corresponding value) and two connections. The keys in the 2-3 tree pointed to by the left connection are smaller than the node, and the keys in the 2-3 tree pointed to by the right link are larger than the node;
- 3-node: it contains two keys (and their corresponding values) and three connections. The keys in the 2-3 tree pointed by the left connection are smaller than the node, the keys in the 2-3 tree pointed by the middle link are between the two keys of the node, and the keys in the 2-3 tree pointed by the right link are larger than the node.
- insert
- Insert a new key into the 2-node: replace the 2-node with a 3-node and save the key to be inserted in it
- Insert a new key into a tree containing only 3-nodes: first, temporarily store the new key in the node to make it a 4-node, and convert the 4-node into a 2-3 tree with 3 2-nodes. One node (root) contains the middle key, one node contains the smallest of the 3 keys, and one node contains the largest of the 3 keys. The height of the tree plus 1
- Insert a new key into a 3-node whose parent node is a 2-node:
- Insert a new key into a 3-node whose parent is a 3-node: