Binary tree (linked list implementation) -- add, delete, change and query

Posted by yarons on Fri, 14 Jan 2022 18:22:19 +0100

Binary tree (linked list implementation)

1.1 basic definition of tree

Tree is a very important data structure in our computer. At the same time, using this data structure can describe many things in real life, such as genealogy, organizational structure of units, and so on.

A tree is a set with hierarchical relations composed of n (n > = 1) finite nodes. It is called "tree" because it looks like an upside down tree, that is, it has roots up and leaves down.

The tree has the following characteristics:

  1. Each node has zero or more child nodes;
  2. Nodes without parent nodes are root nodes;
  3. Each non root node has only one parent node;
  4. Each node and its descendants can be regarded as a tree as a whole, which is called a subtree of the parent node of the current node;

1.2 related terms of tree

Degree of node:

The number of subtrees contained in a node is called the degree of the node;

Leaf node:

A node with a degree of 0 is called a leaf node or a terminal node

Branch node:

A node whose degree is not 0 is called a branch node or a non terminal node

Node hierarchy:

Starting from the root node, the level of the root node is 1, the direct successor level of the root is 2, and so on

Sequence number of node:

The nodes in the tree are arranged into a linear sequence from the upper layer to the lower layer and from left to right in the same layer, and they are compiled into continuous natural numbers.

Degree of tree:

The maximum degree of all nodes in the tree

Height (depth) of the tree:

The maximum level of nodes in the tree

forest:

m (m > = 0) sets of disjoint trees, delete the root node of a non empty tree, and the tree becomes a forest; Add a unified root node to the forest, and the forest will become a tree

Child node:

The direct successor node of a node is called the child node of the node

Parent node (parent node):

The direct precursor of a node is called its parent node

Sibling node:

The child nodes of the same parent node are called brother nodes

1.3 basic definition of binary tree

A binary tree is a tree with a degree of no more than 2 (each node has at most two child nodes)

Full binary tree:

A binary tree is a full binary tree if the node tree of each layer reaches the maximum.

describeformula
Number of nodes in each layerk is the number of layers

Complete binary tree:

Leaf nodes can only appear in the lowest and lower layers, and the nodes of the lowest layer are concentrated in several positions on the left of the layer

1.4 creation of binary search tree

Node API design:

Class nameNode<Key,Value>
Construction methodNode (key, value, node left, node right): creates a node object
Member variable1.public Node left: records the left child node
2.public Node right: records the right child node
3. Public key: storage key
4. Public value: store value

Binary lookup tree API design:

Class nameBinaryTree<Key extends Comparable,Value>
Construction methodBinaryTree(): creates a BinaryTree object
Member variable1.private Node root: records the root node
2.private int N: number of elements in the record tree
Member method1. Public void put (key, value): inserts a key value pair into the tree
2. Private node put (node x, key, value, Val): add a key value pair to the specified tree X and return the added new tree
3. Public value get (key): find the corresponding value from the tree according to the key
4. Private value get (node x, key): find the value corresponding to the key from the specified tree X
5. Public void delete (key): deletes the corresponding key value pair in the tree according to the key
6. Private node delete (node x, key): deletes the key value pair whose key is key on the specified tree x, and returns the deleted new tree
7.public int size(): get the number of elements in the tree
8.public Key min(): find the smallest key in the tree
9.private Node min(Node x): find the node with the smallest key in the specified tree X
10.public Key max(): find the largest key in the tree
11.public Node max(Node x): find the node with the largest key in the specified tree X

Implementation of binary search tree

Implementation idea of insertion method:

1. If there is no node in the current tree, the new node is directly used as the root node

2. If the current tree is not empty, start from the root node:

2.1 if the key of the new node is less than the key of the current node, continue to find the left child node of the current node;

2.2 if the key of the new node is greater than the key of the current node, continue to find the right child node of the current node;

2.3 if the key of the new node is equal to the key of the current node, such a node already exists in the tree. Replace the value value of the node.

Implementation idea of query method get:

Start at the root node:

1. If the key to be queried is less than the key of the current node, continue to find the left child node of the current node;

2. If the key to be queried is greater than the key of the current node, continue to find the right child node of the current node;

3. If the key to be queried is equal to the key of the current node, the value of the current node will be returned in the tree.

Implementation idea of delete method:

1. Find the deleted node;

2. Find the minimum node minNode in the right subtree of the deleted node

3. Delete the smallest node in the right subtree

4. Let the left subtree of the deleted node be called the left subtree of the minimum node minNode, and let the right subtree of the deleted node be called the right subtree of the minimum node minNode

5. Make the parent node of the deleted node point to the minimum node minNode

code:

/**
 * Binary tree
 */
public class BinaryTree<Key extends Comparable<Key>, Value> {
    // Record root node
    private Node root;
    // Record the number of elements in the tree
    private int N;

    public BinaryTree() {
    }

    // Gets the number of elements in the tree
    public int size() {
        return N;
    }

    // Add the element key value to the tree
    public void put(Key key, Value value) {
        root = put(root, key, value);
    }

    // Add key value to the specified tree x, and return the new tree after adding elements
    private Node put(Node x, Key key, Value value) {
        // If the x node is empty, a new node is directly created to store data and return
        if (x == null) {
            // Number of elements + 1
            N++;
            return new Node(key, value, null, null);
        }
        // If the X node is not empty, compare the x.key with the passed in key to find the insertion point
        // If (key > x.key), continue to find the right child node of the current node
        if (key.compareTo(x.key) > 0) {
            x.right = put(x.right, key, value);
        }
        // If (key < x.key), continue to find the left child node of the current node
        if (key.compareTo(x.key) < 0) {
            x.left = put(x.left, key, value);
        }
        // If (key=x.key), replace the value value of the current node
        if (key.compareTo(x.key) == 0) {
            x.value = value;
        }
        return x;
    }

    // The value corresponding to the specified key in the query tree
    public Value get(Key key) {
        return get(root, key);
    }

    // From the specified tree x, find the value corresponding to the key
    private Value get(Node x, Key key) {
        // The x tree is null
        if (x == null)
            return null;
        // x tree is not null
        // If (key < x.key), recursively query the left subtree of the current node
        if (key.compareTo(x.key) < 0) {
            return get(x.left, key);
        }
        // If (key > x.key), recursively query the right subtree of the current node
        if (key.compareTo(x.key) > 0) {
            return get(x.right, key);
        }
        // If (key=x.key), return the value of the current node
        if (key.compareTo(x.key) == 0) {
            return x.value;
        }
        return null;
    }

    // Delete the value corresponding to the key in the tree
    public void delete(Key key) {
        delete(root, key);
    }

    // Delete the value corresponding to the key in the specified tree x, and return the deleted new tree
    private Node delete(Node x, Key key) {
        // If the x node is empty, it will be returned directly
        if (x == null) {
            return null;
        }
        // If the x node is not empty, compare the key value to find the node to be deleted
        // If (key > x.key), find the right subtree of the current node
        if (key.compareTo(x.key) > 0) {
            x.right = delete(x.right, key);
        }
        // If (key < x.key), find the left subtree of the current node
        if (key.compareTo(x.key) < 0) {
            x.left = delete(x.left, key);
        }
        // If (key=x.key), find the node to delete and delete it
        if (key.compareTo(x.key) == 0) {
            // To find the smallest node in the right subtree of X node, replace x node
            // If the right subtree of x node is empty, the left subtree of x is returned directly
            if (x.right == null) {
                // Number of elements - 1
                N--;
                return x.left;
            }
            // If the left subtree of x node is empty, the right subtree of x is returned directly
            if (x.left == null) {
                // Number of elements - 1
                N--;
                return x.right;
            }
            // If both the left and right subtrees of X exist, find the smallest node in the right subtree of X node and replace x node
            Node minNode = x.right;
            while (minNode.left != null) {
                minNode = minNode.left;
            }
            // Delete minNode node in tree
            Node n = x.right;
            while (n.left != null) {
                if (n.left == minNode) {
                    n.left = null;
                }
                n = n.left;
            }
            // Replace the x node with minNode, and make the left and right subtrees of minNode become the left and right subtrees of x
            minNode.left = x.left;
            minNode.right = x.right;
            // Number of elements - 1
            N--;
            // Return to replace subtree after deletion ()
            x = minNode;
        }
        return x;
    }

    // Find the smallest key in the tree
    public Key min() {
        return min(root).key;
    }

    // Finds the node where the smallest key in the specified tree is located
    private Node min(Node x) {
        // Judge whether the x node has left subtree. If it continues to traverse to the left, it is the smallest node
        if (x.left != null) {
            return min(x.left);
        } else {
            return x;
        }
    }

    // Find the largest key in the tree
    public Key max() {
        return max(root).key;
    }

    // Find the node where the largest key is located in the tree
    private Node max(Node x) {
        // Judge whether the x node has a right subtree. If it continues to traverse to the left, it is the largest node
        if (x.right != null) {
            return max(x.right);
        } else {
            return x;
        }
    }

    // Node class
    private class Node {
        // Storage key
        private Key key;
        // Stored value
        private Value value;
        // Record left child node
        private Node left;
        // Record right child node
        private Node right;

        public Node(Key key, Value value, Node left, Node right) {
            this.key = key;
            this.value = value;
            this.left = left;
            this.right = right;
        }
    }
}

Topics: data structure linked list Binary tree