Detailed Explanation of Binary Tree Data Structure

Table of contents

1. What is a binary tree?

2. Binary tree traversal: depth first and breadth first

(1) Depth-first search (DFS) algorithm

(2) Breadth-first search (BFS) algorithm

3. Detailed explanation of the nature of the binary tree

4. Types of binary trees

(1) Full binary tree

(2) Complete binary tree

(3) Binary search tree / binary search tree

(4) Balanced binary tree

(5) Line segment tree


1. What is a binary tree?

        A binary tree is a tree data structure in which each node can have at most two child nodes , called left child and right child. // Time complexity is related to the depth of the tree

        Here is an example tree node with integer data:

class Node {
    int key;
    Node left, right;
 
    public Node(int item)
    {
        key = item;
        left = right = null;
    }
}

        Construct a binary tree using Java code:

public class BinaryTree {

    // Root of Binary Tree
    Node root;

    // Constructors
    BinaryTree(int key) {
        root = new Node(key);
    }

    BinaryTree() {
        root = null;
    }

    public static void main(String[] args) {
        BinaryTree tree = new BinaryTree();

        // 创建根节点
        tree.root = new Node(1);
        /* 下面是上述语句后的树
           1
          / \
        null null
        */

        tree.root.left  = new Node(2);
        tree.root.right = new Node(3);
        /* 2和3是1的左右子结点
              1
             / \
            2   3
           / \ / \
       null null null null */
        tree.root.left.left = new Node(4);
        /* 4变成了2的左子结点
               1
              / \
             2   3
            / \ / \
           4 null null null
          / \
        null null
        */
    }

    private static class Node {

        int key;
        Node left, right;

        public Node(int item) {
            key  = item;
            left = right = null;
        }
    }
}

2. Binary tree traversal: depth first and breadth first

        Unlike linear data structures (arrays, linked lists, queues, stacks, etc.) which only have one logical way to traverse them, trees can be traversed in different ways.

(1) Depth-first search (DFS) algorithm

        Depth-First Traversal (Depth-First Traversal) is a traversal method for binary trees. Its core idea is to visit the nodes of the binary tree as deeply as possible until it can no longer go deeper, and then go back to the previous node to continue traversing. There are three common ways of depth-first traversal: pre-order traversal, in-order traversal , and post-order traversal . // The essence is to visit the root node first or visit the root node later

        1) Preorder Traversal (Preorder Traversal)

        The rule of preorder traversal is to visit the root node first, and then recursively traverse the left and right subtrees in order from left to right. The order of preorder traversal is: root node -> left subtree -> right subtree .

        Code implementation of preorder traversal:

public class BinaryTree {

    // 根节点
    Node root;

    BinaryTree() {
        root = null;
    }

    // 给定一棵二叉树,按顺序打印它的节点
    void printPreorder(Node node) {
        if (node == null) {
            return;
        }
        // 打印当前节点的数据
        System.out.print(node.key + " ");
        // 遍历左子树
        printPreorder(node.left);
        // 遍历右子树
        printPreorder(node.right);
    }

    // Driver code
    public static void main(String[] args) {
        BinaryTree tree = new BinaryTree();
        tree.root            = new Node(1);
        tree.root.left       = new Node(2);
        tree.root.right      = new Node(3);
        tree.root.left.left  = new Node(4);
        tree.root.left.right = new Node(5);

        // Function call
        System.out.println("traversal of binary tree is ");
        tree.printPreorder(tree.root);
    }

    private static class Node {

        int  key;
        Node left, right;

        public Node(int item) {
            key  = item;
            left = right = null;
        }
    }
}

//输出
traversal of binary tree is 
1 2 4 5 3 

        2) Inorder Traversal (Inorder Traversal)

        The rule of in-order traversal is to first recursively traverse the left subtree in order from left to right, then visit the root node, and finally recursively traverse the right subtree. The order of inorder traversal is: left subtree -> root node -> right subtree .

        Inorder traversal has a particularly important application in binary search trees, because inorder traversal traverses nodes in ascending order of value.

        Code implementation of in-order traversal: // Just adjust the traversal order in the above code

    // 给定一棵二叉树,按顺序打印它的节点
    void printInorder(Node node) {
        if (node == null) {
            return;
        }
        // 遍历左子树
        printInorder(node.left);
        // 打印当前节点的数据
        System.out.print(node.key + " ");
        // 遍历右子树
        printInorder(node.right);
    }


//输出
traversal of binary tree is 
4 2 5 1 3 

        3) Postorder Traversal

        The rule of post-order traversal is to recursively traverse the left subtree and right subtree in order from left to right, and then visit the root node. The order of post-order traversal is: left subtree -> right subtree -> root node .

        Code implementation of post-order traversal: // Just adjust the traversal order in the above code

    // 给定一棵二叉树,按顺序打印它的节点
    void printPostorder(Node node) {
        if (node == null) {
            return;
        }
        // 遍历左子树
        printPostorder(node.left);
        // 遍历右子树
        printPostorder(node.right);
        // 打印当前节点的数据
        System.out.print(node.key + " ");
    }

//输出
traversal of binary tree is 
4 5 2 3 1 

(2) Breadth-first search (BFS) algorithm

        Breadth-First Traversal of a binary tree, also known as Level Order Traversal, is a traversal method that visits the nodes of a binary tree layer by layer according to the hierarchical order. Starting from the root node, visit the nodes of each layer in order from left to right until all nodes are traversed. // read layer by layer

        Code implementation of layer order traversal:

public class BinaryTree {

    // 根节点
    Node root;

    BinaryTree() {
        root = null;
    }

    /*层序遍历*/
    void printLevelOrder() {
        int h = height(root);
        int i;
        for (i = 1; i <= h; i++) {
            printCurrentLevel(root, i);
        }
    }

    /* 计算树的高度 -- 从根节点开始沿着最长路径的节点一直到最远的叶节点.*/
    int height(Node root) {
        if (root == null) {
            return 0;
        } else {
            /* 计算每个子树的高度 */
            int lheight = height(root.left);
            int rheight = height(root.right);

            /* use the larger one */
            if (lheight > rheight) {
                return (lheight + 1);
            } else {
                return (rheight + 1);
            }
        }
    }

    /* Print nodes at the current level */
    void printCurrentLevel(Node root, int level) {
        if (root == null) {
            return;
        }
        if (level == 1) {
            System.out.print(root.key + " ");
        } else if (level > 1) {
            printCurrentLevel(root.left, level - 1);
            printCurrentLevel(root.right, level - 1);
        }
    }

    // Driver code
    public static void main(String[] args) {
        BinaryTree tree = new BinaryTree();
        tree.root            = new Node(1);
        tree.root.left       = new Node(2);
        tree.root.right      = new Node(3);
        tree.root.left.left  = new Node(4);
        tree.root.left.right = new Node(5);

        // Function call
        System.out.println("traversal of binary tree is ");
        tree.printLevelOrder();
    }

    private static class Node {

        int  key;
        Node left, right;

        public Node(int item) {
            key  = item;
            left = right = null;
        }
    }
}

//输出
traversal of binary tree is 
1 2 3 4 5 

        The four traversal methods traverse the following tree:

  1. Preorder traversal results: 1-2-4-5-3-6-7
  2. Inorder traversal results: 4-2-5-1-6-3-7
  3. Post-order traversal results: 4-5-2-6-7- 1
  4. Layer sequence traversal results: 1-2-3-4-5-6-7

3. Detailed explanation of the nature of the binary tree

        Binary tree example diagram: //Note that the binary tree does not have the order of the size of the elements, but only stipulates that the number of child nodes is 2

        (1) Property 1: There are at most 2^(i-1) (i≥1) nodes on the i-th layer of the binary tree . // Nodes for each layer

  • If it is the first layer (root node), then the layer has at most 2^(1-1), that is, 2^0 = 1 node.
  • If it is layer 3, then the layer has at most 2^(3-1), which is 2^2 = 4 nodes.

        (2) Property 2 : A binary tree with depth h contains at most 2^h - 1 nodes . // node of the whole tree

  • If the depth of the tree is 1 (only the root node), the entire tree has at most 2^1-1, which is 2 - 1 = 1 node.
  • If the depth of the tree is 3, the whole tree has at most 2^3 - 1, which is 8 - 1 = 7 nodes.

        (3) Property 3: If there are n0 leaf nodes and n2 nodes with degree 2 in any binary tree, then there must be n0 = n2 + 1.

        For example, in the binary tree example diagram, the number of leaf nodes in the diagram is 4 (nodes without child nodes), respectively: 2, 5, 11 , 4, so n0 = 4; there are 3 nodes with degree 2, respectively : 2, 7, 6 ; then there is always: n0 = n2 + 1, in the binary tree described above, that is: 3 + 1 = 4  // It is a bit like the number of leaf nodes is equal to the sum of the number of all previous parent nodes + 1 (full binary tree)

        // Supplement: What is the degree of a binary tree?

        The degree of a binary tree is the maximum value of the degrees of all nodes in the tree. A degree of 1 means that there is only one child node or it is a single subtree, and a degree of 2 means that there are two child nodes or both left and right subtrees. The degree of a binary tree is less than or equal to 2, because the definition of a binary tree requires the degree of any node in a binary tree (node The number of branches) is less than or equal to 2. // Maximum number of nodes

        (4) Property 4: The depth of a full binary tree with n nodes is [log(2)n] + 1. ([ ] means round down)

        As shown in the figure below, a full binary tree has 15 nodes, then [log(2) 15] = 3, then the depth of this binary tree is: 3 + 1 = 4.

        Example of how log(2)n is calculated: From 2^4 = 16, log(2) 16 = 4. 

        // Supplement: What is a full binary tree and a complete binary tree?

        Full binary tree: A binary tree in which all nodes on each level have two child nodes except the last level without any child nodes.

        Complete binary tree: a binary tree with a depth of k and n nodes. The nodes in the tree are numbered from top to bottom and from left to right. If the number is i (1≤i≤n) If the position of the node in the binary tree is the same as that of the node number i in the full binary tree, then this binary tree is called a complete binary tree. // A smaller version of the full binary tree

        (5) Property 5 : If a complete binary tree with n nodes is sequentially numbered (1≤i≤n), then, for the node numbered i (i≥1):

  • When i = 1, the node is the root, it has no parent node.
  • When i > 1, the parent node number of node i is int_down(i/2)   // int_down means rounding down, for example, the parent node of 5 is 2 -> int_down( 5 /2) = 2
  • If 2i ≤ n, there is a left node numbered 2i, otherwise there is no left node. // Nodes 2, 4, and 6 in the figure below
  • If 2i + 1 ≤ n, there is a right node numbered 2i + 1, otherwise there is no right node. // Nodes 3 and 5 in the figure below

4. Types of binary trees

(1) Full binary tree

        Full Binary Tree (Full Binary Tree), also known as strict binary tree, is a special kind of binary tree. In a full binary tree, except for the leaf nodes, each node has two child nodes, and all leaf nodes are located on the same level .

        A full binary tree has the following properties:

  1. All non-leaf nodes have two children.
  2. All leaf nodes are on the same level.
  3. A full binary tree of depth h has 2^h - 1 nodes in total.

        The following is the structure of a full binary tree:

(2) Complete binary tree

        A complete binary tree (Complete Binary Tree) is a special binary tree structure. In a complete binary tree, except for the leaf nodes of the last layer may not be full, the nodes of other layers are full, and the leaf nodes of the last layer are all continuous Sort left.

        If the depth of the binary tree is h, then except the hth layer, the number of nodes in each layer reaches the maximum number, and all the nodes in the hth layer are continuously concentrated on the leftmost.

        The following shows the structure of a complete binary tree:

        A full binary tree is a special form of a complete binary tree. If a binary tree is a full binary tree, it must be a complete binary tree.

(3) Binary search tree / binary search tree

        Binary Search Tree (BST) is an ordered binary tree data structure, in which for any node, the node values ​​in its left subtree are less than the value of the node, and the node values ​​in its right subtree are all greater than the node's value . In short, a binary search tree satisfies the following properties:

        For any node N:

  • The values ​​of all nodes in its left subtree are less than the value of N.
  • The values ​​of all nodes in its right subtree are greater than the value of N.
  • Its left and right subtrees are also binary search trees.

        This property makes the binary search tree have the following characteristics:

  1. In the binary search tree, the node value in the left subtree is smaller than the value of the root node, and the node value in the right subtree is greater than the value of the root node, so the operation of finding a specific value in the binary search tree can be determined by comparing the node value Perform binary search to improve search efficiency .
  2. The results of the inorder traversal of a binary search tree are ordered, that is, in ascending order .

        The following is the structure of a binary search tree:

        Due to the ordered nature of a binary search tree, it can be used as an efficient data storage and retrieval structure. For example, in a database, using a binary search tree can speed up lookup, insertion, and deletion operations, and improve data access efficiency. // Binary search, which will be introduced in detail later

(4) Balanced binary tree

        Balanced Binary Tree (Balanced Binary Tree) is a special binary tree structure, its purpose is to maintain the balance of the tree when inserting and deleting nodes , so as to improve the efficiency of operations such as search, insertion and deletion. // Mainly to reduce the height of the tree to prevent the binary tree from degenerating into a linked list

        A balanced binary tree has the following properties:

  1. For any node, the height difference between the left subtree and the right subtree does not exceed 1 , that is, the absolute value of the difference between the heights of the left subtree and the right subtree does not exceed 1.
  2. Each subtree is a balanced binary tree.

        Common implementations of balanced binary trees include AVL trees and red-black trees . These trees automatically perform balancing operations when inserting or deleting nodes to maintain the balance of the tree. Balance operations include left rotation, right rotation, double rotation , etc. By adjusting the position of the node and the balance factor, the height difference of the tree is kept within an acceptable range.

        The balanced nature of the balanced binary tree ensures that the height of the tree is low, so that the time complexity of operations such as search, insertion, and deletion is kept at the O(log n) level. Compared with unbalanced binary search tree, balanced binary tree has better performance in large-scale data sets and frequent dynamic operation scenarios.

        However, the maintenance of a balanced binary tree comes at an additional cost, for example balancing operations when inserting and deleting nodes may result in high complexity. Therefore, in some specific application scenarios, other more suitable data structures may be selected, such as B-trees or skip lists , to balance performance and complexity requirements.

        The following is the structure of an AVL tree : // The AVL tree will be introduced in detail in other articles later, here is only an introduction

        The following is the structure of a red-black tree : // AVL tree will be introduced in detail in other articles later, here is only an introduction

        A red-black tree is a variant of a balanced binary search tree. The height difference between its left and right subtrees may be greater than 1, so a red-black tree is not a balanced binary tree (AVL) in the strict sense, but the cost of balancing it is relatively low. Low, its average statistical performance is stronger than AVL tree.

        Important property: All paths from any node to each of its leaves contain the same number of black nodes . // black node balance

(5) Line segment tree

        The line segment tree is a binary search tree, similar to the interval tree, which divides an interval into some unit intervals , and each unit interval corresponds to a leaf node in the line segment tree. Using the line segment tree can quickly find the number of times a certain node appears in several line segments, and the time complexity is O(logN).

        The line segment tree is to decompose each interval [L, R] into [L, M] and [M+1, R] (where M = (L+R) / 2 The division here is an integer division, that is, the result is taken whole), until L == R. 

        At the beginning, it is the interval [1,n], and it is decomposed step by step through recursion. Assuming that the height of the root is 1, the maximum height of the tree is (n>1). 

        The line segment tree is unique for each n decomposition, so the line segment tree with the same n has the same structure, which is also the basis for realizing the persistent line segment tree.

        The following figure shows the decomposition process of the interval [1,13]:

        In the figure above, each interval is a node, and each node stores the statistical information of its corresponding interval.

        Summarize:

        The core idea of ​​a line segment tree is to divide a given interval into multiple smaller subintervals, and maintain information related to the interval at each node. Typically, a line segment tree is a balanced binary tree, where each leaf node represents an individual element in the original data, while other nodes represent aggregated information for its corresponding interval.

        The main advantage of the line segment tree is that it can perform interval query and update operations in O(log n) time complexity. By utilizing the special structure of the line segment tree, the involved interval can be quickly located and operated. Line segment trees are often used to solve various interval query problems, such as interval maximum value query, interval modification, interval coverage, etc.

        For recommended reading articles about line segment trees, click " Line Segment Trees ".

Guess you like

Origin blog.csdn.net/swadian2008/article/details/131050189