Binary Search Tree BST

definition

Definition: A BST is a binary tree in which each node contains a Comparable key (and an associated value value) and each node's key is greater than the key of any node in its left subtree and less than the key of any node in its right subtree The key of any node.

data structure

The tree consists of Node objects, each with a pair of keys, two links, and a node counter N. Each Node object is the root node of a subtree containing N nodes. Its left link points to a binary search tree consisting of all keys smaller than the node, and its right link points to a tree with keys larger than the node. A binary search tree of all keys. In the BST class, a Node object root should also be defined, pointing to the root node of the current binary tree.

public class BST<Key extends Comparable<Key>, Value> {
	private class Node {
		private Key key;           //键
		private Value value;       //值
		private Node left,right; //Left subtree and right subtree
		private int N; //The total number of all nodes in the subtree rooted at this node  
		
		public Node(Key key, Value value, int N) {
			//Note that you need to take the total number of nodes N as a parameter
			this.key = key;
			this.value = value;
			this.N = N;
		}
	}
	private Node root; //root node of binary search tree
	
	private int size(Node x) { //As a private method, find the size of each subtree
		if(x == null) 	return 0;
		else 			return x.N;
	}
	
	public int size() { //Public method, find the total number of nodes in the entire tree
		return size(root);
	}
}

Operations on binary search trees

Insert and find operations

These two operations are relatively simple, just look at the code directly:

        public void put(Key key, Value value) {
		//Find the key, find and update its value, otherwise create a new node and get a new binary search tree
		root = put(root, key, value);
	}
	
	private Node put(Node x, Key key, Value value) {
		//If the key exists in the subtree rooted at x, update its value;
		//Otherwise insert the new node with key and value into the appropriate position of the subtree
		if(x == null)  		return new Node(key, value, 1);
		int cmp = key.compareTo(x.key);
		if(cmp < 0)			x.left = put(x.left, key, value);
		else if(cmp > 0)	x.right = put(x.right, key, value);
		else 				x.value = value;
		x.N = size(x.left) + size(x.right) + 1;
		return x;
	}
	
	public Value get(Key key) {
		return get(root, key);
	}
	
	private Value get(Node x, Key key) {
		//Find and return the value corresponding to key in the tree with x as the root node;
		// if not found, return null
		if(x == null) 		        return null;
		int cmp = key.compareTo(x.key);
		if(cmp < 0)			return get(x.left, key);
		else if(cmp > 0)	        return get(x.right, key);
		else 				return x.value;
	}

Here, a public method and a private method are defined to implement an operation, and the operations are implemented recursively. Note that the number of nodes must be changed.

Ordering related methods and delete operations

Max and Min keys

If the left link of the root node is empty, then the smallest key in a binary search tree is the root node; if the left link is not empty, the smallest key in the tree is the smallest key in the left subtree. The same is true for the largest key.

	public Key min() {
		return min(root).key;
	}
	
	private Node min(Node x) {
		if(x.left == null) 	return x;
		return min(x.left);
	}
	
	public Key max() {
		return max(root).key;
	}
	
	private Node max(Node x) {
		if(x.right == null) 	return x;
		return max(x.right);
	}

selection and ranking

	public Key select(int k) {
		//Return the node with rank k, starting from 1
		return select(root, k).key;
	}
	
	private Node select(Node x, int k) {
		if(x == null) return null;//The ranking starts from 1
		int t = size(x.left) + 1;
		if		(t > k) 	return select(x.left, k);
		else if	(t < k) 	return select(x.right, k - t);
		else 				return x;
	}
	
	public int rank(Key key) {
		// Given a node, return its rank
		return rank(root, key);
	}
	
	private int rank(Node x, Key key) {
		if(x == null) 		return 0;
		int cmp = key.compareTo(x.key);
		if		(cmp < 0) 	return rank(x.left, key);
		else if	(cmp > 0) 	return 1 + size(x.left) + rank(x.right, key);
		else return size(x.left) + 1;//The ranking starts from 1
	}

In the select operation, a node with a key rank of k is found, and the rank operation is the opposite, which is to find the rank of a key.

Delete the largest key and the smallest key

Remove the smallest key:

  • Recursively traverse to the left until the left link of the node is empty;
  • Replace the node with the node's right node;
  • Update the number of nodes N of the subtree.
Similarly, deleting the largest key is similar.
	public void deleteMin() {
		root = deleteMin(root);
	}
	
	private Node deleteMin(Node x) {
		//delete the smallest node of the subtree rooted at 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 deleteMax() {
		root = deleteMax(root);
	}
	
	private Node deleteMax(Node x) {
		//delete the largest node of the subtree rooted at node x
		if(x.right == null) return x.left;
		x.right = deleteMax(x.right);
		x.N = size(x.left) + size(x.right) + 1;
		return x;
	}

delete operation

We can delete any node with only one child in a similar way to deleting the smallest key, but how do we delete a node with two children?

Proceed as follows:

  • Save the link to the node to be deleted as t;
  • Point x to its successor node min(t.right);
  • Point the right link of x to deleteMin(t.right), that is, the sub-binary search tree where all nodes are still greater than x.key after deletion;
  • Set the left link of x (empty in the example above) to t.left.

The link and node counters need to be updated after the recursive call.

	public void delete(Key key) {
		root = delete(root, key);
	}
	
	private Node delete(Node x, Key key) {
		//Delete this node of key in the tree with x as the root node
		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(x.right);
			x.right = deleteMin(t.right);
			x.left = t.left;
		}
		x.N = size(x.left) + size(x.right) + 1;
		return x;
	}

The complete code of java implementation

public class BST<Key extends Comparable<Key>, Value> {
	private class Node {
		private Key key;           //键
		private Value value;       //值
		private Node left,right; //Left subtree and right subtree
		private int N; //The total number of all nodes in the subtree rooted at this node  
		
		public Node(Key key, Value value, int N) {
			//Note that you need to take the total number of nodes N as a parameter
			this.key = key;
			this.value = value;
			this.N = N;
		}
	}
	private Node root; //root node of binary search tree
	
	private int size(Node x) { //As a private method, find the size of each subtree
		if(x == null) 	return 0;
		else 			return x.N;
	}
	
	public int size() { //Public method, find the total number of nodes in the entire tree
		return size(root);
	}
	
	public void put(Key key, Value value) {
		//Find the key, find and update its value, otherwise create a new node and get a new binary search tree
		root = put(root, key, value);
	}
	
	private Node put(Node x, Key key, Value value) {
		//If the key exists in the subtree rooted at x, update its value;
		//Otherwise insert the new node with key and value into the appropriate position of the subtree
		if(x == null)  		return new Node(key, value, 1);
		int cmp = key.compareTo(x.key);
		if(cmp < 0)			x.left = put(x.left, key, value);
		else if(cmp > 0)	x.right = put(x.right, key, value);
		else 				x.value = value;
		x.N = size(x.left) + size(x.right) + 1;
		return x;
	}
	
	public Value get(Key key) {
		return get(root, key);
	}
	
	private Value get(Node x, Key key) {
		//Find and return the value corresponding to key in the tree with x as the root node;
		// if not found, return null
		if(x == null) 		return null;
		int cmp = key.compareTo(x.key);
		if(cmp < 0)			return get(x.left, key);
		else if(cmp > 0)	return get(x.right, key);
		else 				return x.value;
	}
	
	public Key min() {
		return min(root).key;
	}
	
	private Node min(Node x) {
		if(x.left == null) 	return x;
		return min(x.left);
	}
	
	public Key max() {
		return max(root).key;
	}
	
	private Node max(Node x) {
		if(x.right == null) 	return x;
		return max(x.right);
	}
	
	public Key select(int k) {
		//Return the node with rank k, starting from 1
		return select(root, k).key;
	}
	
	private Node select(Node x, int k) {
		if(x == null) return null;//The ranking starts from 1
		int t = size(x.left) + 1;
		if		(t > k) 	return select(x.left, k);
		else if	(t < k) 	return select(x.right, k - t);
		else 				return x;
	}
	
	public int rank(Key key) {
		// Given a node, return its rank
		return rank(root, key);
	}
	
	private int rank(Node x, Key key) {
		if(x == null) 		return 0;
		int cmp = key.compareTo(x.key);
		if		(cmp < 0) 	return rank(x.left, key);
		else if	(cmp > 0) 	return 1 + size(x.left) + rank(x.right, key);
		else return size(x.left) + 1;//The ranking starts from 1
	}
	
	public void deleteMin() {
		root = deleteMin(root);
	}
	
	private Node deleteMin(Node x) {
		//delete the smallest node of the subtree rooted at 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 deleteMax() {
		root = deleteMax(root);
	}
	
	private Node deleteMax(Node x) {
		//delete the largest node of the subtree rooted at node x
		if(x.right == null) return x.left;
		x.right = deleteMax(x.right);
		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) {
		//Delete this node of key in the tree with x as the root node
		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(x.right);
			x.right = deleteMin(t.right);
			x.left = t.left;
		}
		x.N = size(x.left) + size(x.right) + 1;
		return x;
	}
	public static void main(String[] args) {
		BST<String, Integer> bst = new BST<String, Integer>();
		bst.put("a", 1);
		bst.put("f", 5);
		bst.put("b", 2);
		bst.put("c", 3);
		System.out.println(bst.max());
		bst.delete("f");
		System.out.println(bst.max());
	}

}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325904249&siteId=291194637