binary search tree
Binary search tree, also called binary sorting tree , is a binary tree or empty tree with the following properties :
- If its left subtree is not empty, the values of all nodes on the left subtree are less than the value of the root node
- If its right subtree is not empty, the values of all nodes on the right subtree are greater than the value of the root node
- Each of its subtrees is also a binary search tree.
Insertion into a binary search tree is very simple:
- Start the comparison from the root node. If it is greater than the root node, traverse the right subtree; if it is less than the root node, traverse the left subtree.
- Perform the above operations on all subtrees
- Until an empty node is traversed, insert the element to be inserted into this empty node.
public class BinarySearchTree {
public static class TreeNode {
public int key;
public TreeNode left;
public TreeNode right;
TreeNode(int key) {
this.key = key;
}
}
public TreeNode root;
/**
* 插入一个元素
*/
public boolean insert(int key) {
TreeNode tmp = new TreeNode(key);
if (this.root == null) {
this.root = tmp;
return true;
}
TreeNode privat = this.root;
TreeNode p1 = this.root;
while (p1 != null) {
privat = p1;
if (p1.key > key) {
p1 = p1.left;
}else {
p1 = p1.right;
}
}
if (privat.key > key) {
privat.left = tmp;
}else {
privat.right = tmp;
}
return true;
}
}
Searching in a binary search tree:
- Start the comparison from the root node. If it is greater than the root node, traverse the right subtree; if it is less than the root node, traverse the left subtree.
- Perform the above operations on all subtrees
//查找key是否存在
public TreeNode search(int key) {
if (this.root == null){
return null;
}
TreeNode tmp = this.root;
while (tmp != null) {
if (tmp.key > key) {
tmp = tmp.left;
}else if (tmp.key < key) {
tmp = tmp.right;
}else {
return tmp;
}
}
return null;
}
Deleting a binary search tree is more complicated because you need to ensure that the deleted tree is still a binary search tree.
Deletion of binary search tree:
There are two situations:
- The left or right tree is empty
- When the left tree of the node to be deleted is empty , make the parents of the node to be deleted point to its right subtree.
- When the right tree of the node to be deleted is empty , make the parent of the node to be deleted point to its left subtree.
- Neither the left nor right subtree is empty
- Find the leftmost (right) node of the right (left) subtree
- Swap the values of two nodes
- Delete the node
//删除key的值
public boolean remove(int key) {
if (this.root == null) {
return false;
}
TreeNode tmp = this.root;
TreeNode privat = tmp;
while (tmp != null) {
if (tmp.key > key) {
privat = tmp;
tmp = tmp.left;
}else if (tmp.key < key) {
privat = tmp;
tmp = tmp.right;
}else {
break;
}
}
if (tmp == null) {
return false;
}
//左树或者右树为空
if (tmp.left == null || tmp.right == null) {
if (tmp.left == null) {
if (tmp == this.root) {
this.root = tmp.right;
}else {
if (privat.left == tmp) {
privat.left = tmp.right;
}else {
privat.right = tmp.right;
}
}
}else {
if (tmp == this.root) {
this.root = tmp.left;
}else {
if (privat.left == tmp) {
privat.left = tmp.left;
}else {
privat.right = tmp.left;
}
}
}
}else {
//左右子树都不为空
TreeNode a = tmp.right;
while(a.left != null) {
privat = a;
a = a.left;
}
tmp.key = a.key;
if (privat.left == a) {
privat.left = a.right;
}else {
privat.right = a.right;
}
}
return true;
}
Set and Map
Map and set are containers or data structures specially used for searching , and their search efficiency is related to their specific instantiated subclasses .
Generally, the searched data is called a keyword (Key) , and the data corresponding to the keyword is called a value (Value) , which is called a Key-value pair.
There are two models:
- Pure key model:
There is an English dictionary to quickly search whether a word is in the dictionary. Quickly search whether a name is in the address book.
- Key-Value model:
Count the number of times each word appears in the file. The statistical result is that each word has a corresponding number of times: <word, number of times a word appears> .
Map.Entry
Map.Entry<K, V> is an internal class implemented inside Map to store the <key, value> key-value pair mapping relationship.
There are several methods in it:
method explain K getKey() Return the key in entry V getValue() Return the value in entry V setValue(V value) Replace the value in the key-value pair with the specified value
Map
- Map is an interface and cannot directly instantiate objects. If you want to instantiate an object, you can only instantiate its implementation class TreeMap or HashMap.
- The Key that stores key-value pairs in the Map is unique , and the value can be repeated.
- When inserting a key-value pair into a TreeMap, the key cannot be empty , otherwise a NullPointerException will be thrown, and the value can be empty . But both the key and value of HashMap can be empty .
- All Keys in Map can be separated and stored in Set for access (because Key cannot be repeated).
- The values in the Map can all be separated and stored in any sub-collection (values may be duplicated).
- The key of the key-value pair in the Map cannot be modified directly , but the value can be modified . If you want to modify the key, you can only delete the key first and then reinsert it.
public static void main(String[] args) {
Map<Integer,Integer> map = new HashMap<>();
Map<Integer,Integer> map1 = new TreeMap<>();
}
Map underlying structure | TreeMap | HashMap |
underlying structure | red black tree | hash bucket |
Insertion/deletion/search time complexity |
O(1) | |
Is it in order? | About Key order | disorder |
Thread safety | not safe | not safe |
Insert/delete/find differences | Element comparison is required | Calculate hash address through hash function |
Compare and overwrite | The key must be comparable, otherwise a ClassCastException will be thrown |
Custom types need to override the equals and hashCode methods |
Application scenarios | In scenarios where Key ordering is required | It doesn’t matter whether the Key is in order or not, higher time performance is required. |
method | explain |
V get(Object key) | Return the value corresponding to key |
V getOrDefault(Object key, V defaultValue) | Returns the value corresponding to the key. If the key does not exist, the default value is returned. |
V put(K key, V value) | Set the value corresponding to the key |
V remove(Object key) | Delete the mapping relationship corresponding to the key |
Set<K> keySet() | Returns a unique set of all keys |
Collection<V> values() | Returns a repeatable collection of all values |
Set<Map.Entry<K, V>> entrySet() | Return all key-value mapping relationships |
boolean containsKey(Object key) | Determine whether key is included |
boolean containsValue(Object value) | Determine whether value is included |
Set
- Set is an interface class inherited from Collection
- Only the key is stored in Set , and the key must be unique
- The bottom layer of TreeSet is implemented using Map , which uses a default object of key and Object as a key-value pair to be inserted into the Map.
- The biggest function of Set is to deduplicate the elements in the set
- Commonly used classes that implement the Set interface include TreeSet and HashSet , and there is also a LinkedHashSet. LinkedHashSet maintains a doubly linked list based on HashSet to record the insertion order of elements.
- The Key in the Set cannot be modified. If you want to modify it, delete the original one first and then reinsert it.
- Null keys cannot be inserted into TreeSet, but they can be inserted into HashSet .
Set underlying structure | TreeSet | HashSet |
underlying structure | red black tree | hash bucket |
Insertion/deletion/search time complexity |
O(1) | |
Is it in order? | Key in order | Not necessarily in order |
Thread safety | not safe | not safe |
Insert/delete/find differences | Insert and delete according to the characteristics of red-black tree | 1. First calculate the key hash address 2. Then insert and delete |
Compare and overwrite | The key must be comparable , otherwise a ClassCastException will be thrown |
Custom types need to override the equals and hashCode methods |
Application scenarios | In scenarios where Key ordering is required | It doesn’t matter whether the Key is in order or not, higher time performance is required. |