Sword finger offer tree

Related concepts

tree


(1) Tree: tree is a recursively defined data structure and an important non-linear data structure. A tree can be an empty tree without any nodes, or a non empty tree with at least one node.

(2) Root: a non empty tree with only one node. That node is the root.

(3) Subtree: in a non empty tree, all nodes except root can be divided into m (m ≥ 0) disjoint sets. Each set itself is a tree, called the root subtree.

(4) Node: represents the elements in the tree and some branches pointing to its subtree.

(5) Degree of a node: the number of subtrees owned by a node is called the degree of the node.

(6) Leaf: a node with a degree of 0.

(7) Child: the root of the node tree is called the child of the node.

(8) Parents: the upper node of a child's node is called the parents of the node.

(9) Sibling: a child of the same parents.

(10) Degree of tree: the maximum degree of nodes in a tree.

(11) Level of node: define the root as the first level from the root node, its child as the second level, and so on.

(12) Depth: the value of the maximum level of nodes in the tree.

(13) Ordered tree: the ordered tree refers to the one in which all the subtrees are ordered from left to right.

(14) Disordered tree: the disordered trees in the tree are called disordered trees.

(15) Forest is a collection of M (m ≥ 0) disjoint trees.

(16) Ancestor: refers to all nodes from the root node to this node.

Two fork tree

1. concept

(1) Each node has at most two subtrees, that is, there is no node with degree greater than 2 in the binary tree. The subtrees of a binary tree can be divided into left and right ones. The order of the left and right children cannot be reversed.

(2) There are five forms of binary trees:

(1) Empty binary tree.
(2) There is only one root node.
(3) There are only root nodes and left subtrees.
(4) There are only root nodes and right subtrees.
(5) There are root nodes and left and right subtrees.

(3) Full binary tree
A binary tree with a depth of K and 2k-1 nodes is called a full binary tree

(4) Complete binary tree
If there is a binary tree with depth k and n nodes, it is called a complete binary tree if and only if each node corresponds to the nodes numbered from 1 to n in the full binary tree with depth k.

(5) Binary search tree

  • Each node contains a key, also known as the data field of data
  • When the left subtree is not empty, each node value of the left subtree is smaller than the value of the root node, that is, l < p
  • When the right subtree is not empty, each node value of the right subtree is greater than the value of the root node, that is, P < R
  • Duplicate values are not allowed for nodes
  • The left and right subtrees of any node conform to the above rules
  • Middle order traversal can make nodes ordered
  • The left and right subtrees of any node are also binary search trees

2. nature

(1) There are at most 2i-1(i ≥ 1) on the i-th layer of a binary tree.

(2) A binary tree with a depth of K has at most 2k-1 nodes (K ≥ 1).

(3) For any binary tree, if n0, n1 and n2 represent node trees with degrees of 0, 1 and 2 respectively, then n0=n2+1.

(4) The depth of a complete binary tree with n nodes is log2n + 1.

(5) For a complete binary tree with n nodes, for any node i (1 ≤ I ≤ n), there are:

  • If i=1, then node I is the root node of the binary tree, without parents; if I > 1, then PARENT(i) is node i/2.
  • If 2i > N, node i has no left child (node I is leaf node); otherwise, its left child LCHILD(i) node 2i.
  • If 2i+1 > N, node i has no right child; otherwise, its right child RCHILD(i) is node 2i+1.

3. storage

(1) Sequential storage structure

The sequential storage structure is only suitable for the storage of complete binary tree, that is to store the complete binary tree from top to bottom and from left to right in a continuous storage space. Generally stored in one-dimensional array.

The sequence storage structure of the complete binary tree in the above figure is as follows:

(2) Chain storage structure

The chain storage structure has two fork linked list structure and three fork linked list storage structure. Generally, binary list is used for storage.
The node structure of binary list is defined as follows:

typedef struct bitnode
{
	int num;
	struct bitnode *lchild;
	struct bitnode *rchild;
}TreeNode;

4. traversal

There are three ways of traversing binary tree: pre order traversal, middle order traversal and post order traversal

(1) Implementation of preamble traversal code

Recursive implementation
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
//Recursive implementation of preorder traversal
void travPre_R(TreeNode* pRoot)
{
    if(pRoot==NULL)//The condition for the end of recursion is that the node is empty
        return;
    cout<<pRoot->val;//Output root
    travPre_R(pRoot->left);//Traverse left subtree
    travPre_R(pRoot->right);//Traversal right subtree
}
Iterative implementation




struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};

//Create a function to access the nodes on the left chain of the binary tree, starting from the current node and going further along the left branch
void visitAlongLeftBranch(TreeNode* pRoot,stack<TreeNode*>& s)
{
    while(pRoot)
    {
        cout<<pRoot->val;//Access current node
        if(pRoot->right)//If there is a right node, first stack the right node
            s.push(pRoot->right);
        pRoot=pRoot->left;//Drill down left branch
    }
}

//Functions of traversal of preorder by iteration
void travPre_l(TreeNode* pRoot)
{
    stack<TreeNode*> s;//Create an auxiliary stack to store the right node
    while(true)
    {
        visitAlongLeftBranch(pRoot,s);//Starting from the current node, visit the left node from top to bottom
        if(s.empty())//The stack is empty, indicating that all nodes have been accessed, ending the cycle
            break;
        pRoot=s.pop();//Pop up start of next batch
    }
}

(2) Middle order ergodic

Recursive implementation:
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
//Recursive implementation of middle order traversal
void travPre_R(TreeNode* pRoot)
{
    if(pRoot==NULL)//The condition for the end of recursion is that the node is empty
        return;
    travPre_R(pRoot->left);//Traverse left subtree
    cout<<pRoot->val;//Output root
    travPre_R(pRoot->right);//Traversal right subtree

}
Iterative implementation:

//Create a function to start from the current node and continue to deepen along the left branch until there is no node with left branch
void goAlongLeftBranch(TreeNode* pRoot,stack<TreeNode*>& s)
{
    while(pRoot)
    {
        s.push(pRoot);//Stack the current node
        pRoot=pRoot->left;//Drill down the left branch and iterate until there is no left child
    }
}

//Functions of middle order traversal by iteration
void travIn_l(TreeNode* pRoot)
{
    stack<TreeNode*> s;//Create an auxiliary stack to store the right node
    while(true)
    {
        goAlongLeftBranch(pRoot,s);//Starting from the current node, stack the left node in sequence from top to bottom
        if(s.empty())//The stack is empty, indicating that all nodes have been accessed, ending the cycle
            break;
        pRoot=s.pop();//pRoot is the lowest node on the left chain
        cout<<pRoot->val;
        pRoot=pRoot->right;//Visit its right subtree again
    }
}

(3) Postorder ergodic

Recursive implementation
//Recursive implementation of post order traversal
void travPre_R(TreeNode* pRoot)
{
    if(pRoot==NULL)//The condition for the end of recursion is that the node is empty
        return;
    travPre_R(pRoot->left);//Traverse left subtree
    travPre_R(pRoot->right);//Traversal right subtree
    cout<<pRoot->val;//Output root

}

Exercise 1: rebuilding a binary tree

Title Description

Enter the results of the preorder traversal and inorder traversal of a binary tree, and rebuild the binary tree. It is assumed that the results of the input preorder traversal and preorder traversal do not contain duplicate numbers. For example, if the sequence {1,2,4,7,3,5,6,8} and the sequence {4,7,2,1,5,3,8,6} are input, the binary tree will be reconstructed and returned.

Principle and train of thought



Method steps

1. The first element pre[0] of preorder traversal is the value of the root node. According to the value of the root node, find the location gen of the root node in the preorder traversal
2. Left subtree:
(1) Use VIN left to store the middle order traversal sequence of left subtree, and save vin[0]-vin[gen-1] to VIN left in turn (use vector's push back function)
(2) Pre left is used to store the pre traversal sequence of left subtree, and pre[1]-pre[gen] is stored in pre left in turn (i+1 is because pre[0] is the root node, and pre left is stored from pre[1])
3. Right subtree:
(1) In this paper, vin[gen+1]-vin[len-1] is successively stored in VIN [u right [i]
(2) Pre right [i] is used to store the traversal sequence of the right subtree, and vin[gen+1]-vin[len-1] is successively stored in pre right [i]
4. Recursion: reconstruct left and right subtrees respectively according to the same method until the leaf node, i.e. until the length of the new traversal sequence is 0 (so it is necessary to judge whether the length len of the traversal sequence is 0 at the beginning)
5. Return to the root node.


Code

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        int len=vin.size();//Length of traversal sequence
        if (len==0)
            return NULL;
        TreeNode *root=new TreeNode(pre[0]);//A new node is defined to represent the root node. The value of the root node is the first element traversed in the previous order

        vector<int> pre_left,pre_right,vin_left,vin_right;//Store the left and right subtrees of preorder traversal and middle order traversal respectively
        
        //Find the location of root node in middle order traversal
        int gen=0;//gen represents the location of the root node
        for (int i = 0; i < len; ++i)
        {
            if (vin[i]==pre[0])
            {
                gen=i;
                break;
            }
        }
        //Left tree
        for (int i = 0; i < gen; ++i)
        {
            vin_left.push_back(vin[i]);//The middle order traversal elements of the left subtree are successively stored in VIN? Left
            pre_left.push_back(pre[i+1]);
        }
        //Right subtree
        for (int i = gen+1; i < len; ++i)
        {
            vin_right.push_back(vin[i]);
            pre_right.push_back(pre[i]);
        }
        root->left=reConstructBinaryTree(pre_left,vin_left);
        root->right=reConstructBinaryTree(pre_right,vin_right);
        return root;
    }
};

Exercise 2: the substructure of the tree

Title Description

Input two binary trees a and B to determine whether B is a substructure of A. (ps: we agree that an empty tree is not a substructure of any tree)

Sword finger offer (10) -- robustness of code

Exercise 3: binary tree mirroring

Title Description

Operate the given binary tree and transform it into a mirror image of the source binary tree.

Sword finger offer (11) -- drawing to visualize abstract problems

Exercise 4: print the binary tree from top to bottom

Title Description

Each node of the binary tree is printed from top to bottom, and the nodes of the same layer are printed from left to right.
Sword finger offer (12) -- concrete abstract problems with examples

Exercise 5: post order traversal sequence of binary search tree

Title Description

Input an integer array to determine whether the array is the result of the subsequent traversal of a binary search tree. If Yes, output Yes; otherwise, output No. Suppose that any two numbers of the input array are different from each other.
Sword finger offer (12) -- concrete abstract problems with examples

Exercise 6: the path of a value in a binary tree

Title Description

Input the root node and an integer of a binary tree, and print out all paths whose sum of node values in the binary tree is the input integer. Path is defined as a path from the root node of the tree to the node that the leaf node passes through. (Note: in the list of returned values, the array with large array length is first)
Sword finger offer (12) -- concrete abstract problems with examples

Exercise 7: binary search tree and double linked list

Title Description

Input a binary search tree, and transform the binary search tree into a sorted bidirectional linked list. It is required that no new node can be created, only the node pointer in the tree can be adjusted.

Sword finger offer (XIII) -- simplify complex problems by decomposition

Published 29 original articles, won praise and 391 visitors
Private letter follow

Posted by bingo333 on Tue, 03 Mar 2020 23:36:03 -0800