Binary search tree, Set and Map (JAVA)

binary search tree

Binary search tree, also called binary sorting tree , is a binary tree or empty tree with the following properties :

  1. 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
  2. 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
  3. Each of its subtrees is also a binary search tree.

Insertion into a binary search tree is very simple:

  1. 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.
  2. Perform the above operations on all subtrees
  3. 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:

  1. 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.
  2. 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
  1. 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.
  2. 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
  1. Find the leftmost (right) node of the right (left) subtree
  2. Swap the values ​​of two nodes
  3. 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(\log_{2}N) 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(\log_{2}N) 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.

Guess you like

Origin blog.csdn.net/2302_76339343/article/details/133500003