Data structure ---- binary tree

Keywords: data structure

1. Tree structure

1.1 definitions

Tree is a nonlinear data structure, which is composed of n( n ≥ 0 n\geq0 n ≥ 0) finite nodes form a set with hierarchical relationship. It is called a tree because it looks like an upside down tree, that is, it has roots up and leaves down.
The tree has the following characteristics:

  • There is a special node, called the root node, which has no precursor node.
  • Except the root node, the other nodes are divided into m (M > 0) disjoint sets T 1 , T 2 , . . . . . . , T m T_1,T_2,......,T_m T1, T2,..., Tm, each set T i ( 1 ≤ i ≤ m ) T_i(1\leq i\leq m) Ti (1 ≤ i ≤ m) is a subtree similar to a tree. The root node of each subtree has and only has one precursor, which can have 0 or more successors.
  • Trees are recursively defined.

be careful:

  1. In the tree structure, there can be no intersection between subtrees, otherwise it is not a tree structure.
  2. In addition to the root node, each node has only one parent node.
  3. A tree with N nodes has N-1 edges. (looking from bottom to top)

1.2 concept

  1. Degree of A node: the number of subtrees of A node is called the degree of the node; For example, in the above figure, the degree of A is 6
  2. Tree degree: the maximum degree of all nodes in a tree is called the degree of the tree; For example, in the above figure, the degree of the tree is 6
  3. Leaf node (terminal node): a node with a degree of 0 is called a leaf node; For example, in the figure above, nodes B, C, H, I... Are leaf nodes.
  4. Parent node (parent node): if A node contains A child node, this node is called the parent node of its child node; For example, in the above figure, A is the parent node of B.
  5. Child node (child node): the root node of the subtree in the meaning of a node is called the child node of the node; For example, in the above figure, B is the child node of A.
  6. Root node: A node in A tree without parent nodes; For example, in the figure above, A is the root node.
  7. Node hierarchy: defined from the root, the root is the first layer, and the child nodes of the root are the second layer, and so on.
  8. Height or depth of tree: the maximum level of nodes in the tree; As shown in the figure above: the height of the tree is 4
    The following concepts only need to be understood
  9. Non terminal node or branch node: a node whose degree is not 0; As shown in the figure above; A. D, E, J, F, G, these nodes are branch nodes.
  10. Sibling node: nodes with the same parent node are called sibling nodes; For example, B and C in the above figure.
  11. Cousin node: the node with both parents on the same layer is a cousin node; For example, H and I in the above figure.
  12. Ancestor of a node: the parents of a node, the parents of both parents... Are the ancestors of the node. Note that the root node is the ancestor of all child nodes. Parents are a collective concept.
  13. Descendant: any node in the subtree with a node as the root is called the descendant of the node. As shown in the figure above, all nodes are descendants of A.
  14. Forest: by M( m ≥ 0 m\geq 0 The collection of m ≥ 0) disjoint trees is called forest.

1.3 representation of tree

Tree structure is more complex than linear table, and it is more troublesome to store. In fact, there are many representations of trees, such as parent representation, child representation, child parent representation and child brother representation. Let's briefly understand the expression of children's brothers:

class Node{
int value;//Data stored in the tree
Node firstChild;//First child quote
Node nextBrother;//Next brother reference

2. Binary tree

2.1 concept

A binary tree is a finite set of nodes, which:

  1. Or empty
  2. Or it is composed of a root node and two binary trees called left subtree and right subtree respectively.

As can be seen from the above figure:

  1. There is no node with degree greater than 2 in binary tree.
  2. The subtree of a binary tree can be divided into left and right, and the order cannot be reversed. Therefore, a binary tree is an ordered tree.

Note: any binary tree is composed of the following cases.

2.2 two special binary trees

  1. Full binary tree: a binary tree. If the node tree of each layer reaches the maximum, the binary tree is a full binary tree. That is, if the number of layers of a binary tree is K and the number of summary points is 2 K − 1 2^K-1 2K − 1, then it is a full binary tree.
  2. Complete binary tree: a complete binary tree is a highly efficient data structure. A complete binary tree is derived from a full binary tree. A binary tree with depth k and N nodes is called a complete binary tree if and only if each node corresponds to the nodes numbered from 0 to n-1 in the full binary tree with depth k.

    Note: the k-1 layer of a complete binary tree is full, and the k layer is continuously left.

2.3 properties of binary tree

  1. If the number of layers of the specified root node is 1, there are at most on layer i of a non empty binary tree 2 i − 1 ( i > 0 ) 2^{i-1}(i>0) 2i − 1 (I > 0) nodes.
  2. If the depth of a binary tree with only root nodes is specified as 1, the maximum number of nodes of a binary tree with depth k is 2 k − 1 ( k ≥ 0 ) 2^{k}-1(k\geq0) 2k−1(k≥0).
  3. For any tree, if the number of leaf nodes is n 0 n_0 n0, the number of non leaf nodes with degree 2 is n 2 n_2 n2, there is n 0 = n 2 + 1 n_0=n_2+1 n0​=n2​+1.

Formula derivation: suppose the total number of nodes in the binary tree is n, the number of nodes with degree 0 is n0, and the number of nodes with degree 1 is n 1 n_1 n1, and the number of nodes with degree 2 is n 2 n_2 n2. Then you can get
N = n 0 + n 1 + n 2 N=n_0+n_1+n_2 N=n0 + n1 + n2 -------- Formula 1
The total number of nodes in the binary tree is N, and there are N-1 edges in the binary tree ----- from bottom to top,
n 0 n_0 Node of n0 ----- leaf node: it is impossible to produce an edge down
n 1 n_1 Node of n1 ---- node with only one child: only one edge can be generated down
n 2 n_2 Node of n2 ---- node of two children: two edges can be generated from the bottom
Use the total number of sides to establish the equation:
N − 1 = n 1 + 2 ∗ n 2 N-1=n_1+2*n_2 N − 1=n1 + 2 * n2 -------- formula 2
Combine equation 1 and equation 2 to obtain n 0 = n 2 + 1 n_0=n_2+1 n0​=n2​+1.

  1. The depth k of a complete binary tree with n nodes is l o g 2 ( n + 1 ) log_2(n+1) log2 (n+1) rounded up.
  2. For a complete binary tree with n nodes, if all nodes are numbered from 0 in the order from top to bottom and from left to right, there are for the node with sequence number i;
  • If I > 0, parental serial number: (i-1)/2; i=0, I is the root node number, no parent node;
  • If 2i+1 < n, left child serial number: 2i+1, otherwise there is no left child;
  • If 2i+2 < n, right child serial number: 2i+2, otherwise right child;

2.4 storage of binary tree

The storage structure of binary tree is divided into sequential storage and chain storage similar to linked list.
Sequential storage: suitable for storing complete binary trees;
Chain structure: storage of any binary tree;
Question: why is a complete binary tree more suitable for sequential structure storage?
The chain storage of binary tree is referenced by nodes one by one. The common representations include binary and trigeminal representations, as follows:

//Child representation
class Node{
int val;//Data domain
Node left;//The reference of the left child often represents the whole left subtree with the left child as the root
Node right;//The reference of the right child often represents the whole right subtree with the right child as the root
}
//Child parent representation
class Node{
int val;//Data domain
Node left;//The reference of the left child often represents the whole left subtree with the left child as the root
Node right;//The reference of the right child often represents the whole right subtree with the right child as the root
Node parent;//Root node of current node

Note: This paper uses child representation to construct binary tree.

2.5 basic operation of binary tree

2.5.1 pre description

  before learning the basic operations of binary tree, you need to create a binary tree before you can learn its related basic operations. In order to be more efficient, we first manually and quickly create a binary tree, quickly enter the binary tree operation learning, and then come back to study the real creation method of binary tree when the binary tree is almost understood.

public class BinaryTree {
    public static class BTNode {
        BTNode left;//Reference the left child of the current node
        BTNode right;//Reference the right child of the current node
        int value;

        public BTNode(int value) {
            this.value = value;
        }
    }
        BTNode root;//Points to the root node of the binary tree

        //Create a binary tree manually
        public void createBinaryTree(){
            BTNode node1=new BTNode(1);
            BTNode node2=new BTNode(2);
            BTNode node3=new BTNode(3);
            BTNode node4=new BTNode(4);
            BTNode node5=new BTNode(5);
            BTNode node6=new BTNode(6);

            node1.left=node2;
            node2.left=node3;
            node1.right=node4;
            node4.left=node5;
            node4.right=node6;
            root =node1;
        }

public static void main(String[] args) {
            BinaryTree bt=new BinaryTree();
            bt.createBinaryTree();

        }
}

Note: the above code is not the way to create a binary tree. The way to create a binary tree will be described in detail later.
Binary tree:

  1. Empty tree;
  2. Non empty: the root node is composed of the left subtree of the root node and the right subtree of the root node.
  3. The definition of binary tree is recursive, and the subsequent basic operations are basically implemented according to this concept.

2.5.2 traversal of binary tree

  1. Preorder traversal
      the simplest way to learn the binary tree structure is to traverse. Traversal is to visit each node in the tree once and only once along a search route. The operation of accessing the node depends on the specific application problem (for example, print the node content and add 1 to the node content). Traversal is one of the most important operations on binary tree and the basis of other operations on binary tree.
       when traversing a binary tree, if there is no agreement, everyone traverses it in their own way, and the results are chaotic. If the agreement is made according to some rules, everyone must have the same traversal result for the same tree. If N represents the root node, L represents the left subtree of the root node, and R represents the right subtree of the root node, there are the following traversal methods according to the order of traversing the root node:
  • NLR: preorder traversal - access root node - left subtree of root - right subtree of root.
  • LNR: middle order traversal - left subtree of root - access root node - right subtree of root.
  • LRN: post order traversal - left subtree of the root - right subtree of the root - access the root node.
 //Wrap recursion one more layer
       public void preOrder(){
           System.out.println("Preorder traversal:");
            preOrder(root);
           System.out.println();
        }

     public void inOrder(){
            System.out.println("Middle order traversal:");
            inOrder(root);
            System.out.println();
        }

        public void postOrder(){
            System.out.println("Post order traversal:");
            postOrder(root);
            System.out.println();
        }

        public int size(){
            return size(root);
        }

        //Binary tree is not empty -- the sequence traversal of binary tree needs to be completed with the help of queue
        //Queue<>

        //Preorder traversal - root node - left subtree - right subtree
        //Operation: print the value field in the node
        public void preOrder(BTNode treeRoot){
           /* if(null==root){
                return;
            }
            //Non empty
            //1.First traverse the root node
            System.out.print(root.value+" ");
            //2.Then traverse the left subtree of the root node ---- note: the left subtree of the root node is also a binary tree. The rules for traversing the left subtree of the root node are the same as those for traversing the original tree
            preOrder(root.left);
            //3.Finally, traverse the right subtree of the root node
            preOrder(root.right);*/

            //Simplified code
            if(treeRoot!=null){
                System.out.print(treeRoot.value+" ");
                preOrder(treeRoot.left);
                preOrder(treeRoot.right);
            }
        }

        //Medium order traversal
    private void inOrder(BTNode treeRoot){
            if(treeRoot!=null){
                inOrder(treeRoot.left);
                System.out.print(treeRoot.value+" ");
                inOrder(treeRoot.right);
            }

    }
    //Postorder traversal
    private void postOrder(BTNode treeRoot){
            if(treeRoot!=null){
                postOrder(treeRoot.left);
                postOrder(treeRoot.right);
                System.out.print(treeRoot.value+" ");
            }
    }
  1. level traversal
    In addition to pre order traversal, middle order traversal and post order traversal, sequence traversal of binary trees can also be carried out. Assuming that the number of layers where the root node of the binary tree is located is 1, sequence traversal starts from the root node of the binary tree, first visit the root node of the first layer, then visit the nodes on the second layer from left to right, and then the nodes on the third layer. By analogy, the process of accessing the nodes of the tree layer by layer from top to bottom and from left to right is sequence traversal.

2.5.3 basic operation of binary tree

//Gets the number of nodes in the binary tree
        private int size(BTNode treeRoot){
            if(treeRoot==null){
                return 0;
            }
            return 1+size(treeRoot.right)+size(treeRoot.left);
        }
//Get the number of leaf nodes
//When the program recurses down, there is no need to continue to recurse down when it encounters a leaf node -- this recursion exits directly
//Get the number of leaf nodes in the binary tree:
        private int getLeafNode(BTNode treeRoot){
            if(treeRoot==null){
                return 0;
            }
            if(treeRoot.right==null&&treeRoot.left==null){
                return 1;
            }
            return getLeafNode(treeRoot.left)+getLeafNode(treeRoot.right);
        }
 //Get the number of nodes in the k-th layer of the binary tree - think that the root is in the first layer
    private int getKLevelNode(BTNode treeRoot,int k){
            if(treeRoot==null||k<=0){
                return 0;
            }
            //k==1, Description: get the number of nodes in the first layer. The first layer has only root nodes
        if(k==1){
            return 1;
        }
        return getKLevelNode(treeRoot.left,k-1)+getKLevelNode(treeRoot.right,k-1);
    }
//Gets the height of the tree
        private int height(BTNode treeRoot){
            if(treeRoot==null){
                return 0;
            }
            int leftHeight=height(treeRoot.left);
            int rightHeight=height(treeRoot.right);
            
            return leftHeight>rightHeight?leftHeight+1:rightHeight+1;
        }
 //Find the node with value and return
        private BTNode find(BTNode treeRoot,int value){
            if(treeRoot==null){
                return null;
            }
            if(treeRoot.value==value){
                return treeRoot;
            }
            BTNode ret=find(treeRoot.left,value);
            if(ret!=null){
                return ret;
            }

            return find(treeRoot.right,value);//If you can't find the left subtree, go to the right subtree
        }

Posted by REDFOXES06 on Sun, 31 Oct 2021 20:46:11 -0700