Data structure THU2018-tree

1. Tree node definition

Insert picture description here
Insert picture description here

Each node points to a parent (except the root node), and each node can have a left child and a right child.

struct Node{
    
    
    Node* parent = NULL;
    Node* left_child = NULL;
    Node* right_child = NULL;
    int data = -1;
    Node(int e){
    
    
        data = e;
    }
    Node* InsertAsLC(int e){
    
     //插入左节点
        Node* lc = new Node(e);
        this->left_child = lc;
        this->left_child->parent = this;
        return lc;
    }
    Node* InsertAsRC(int e){
    
     //插入左节点
        Node* rc = new Node(e);
        this->right_child = rc;
        this->right_child->parent = this;
        return rc;
    }
    int size(){
    
     // 返回树的规模
        if(!this)
            return 0;
        if(!left_child && !right_child)
            return 1;
        return 1+left_child->size()+right_child->size();
    }
};

2. Tree traversal

2.1 Pre-order traversal

Visit the root node first, then the left child, and finally the right child:
Insert picture description here

2.1.1 Recursive solution
void preorder_traverse(Node* root){
    
     //树的先序遍历
    if(root == NULL)
        return;
    cout<<root->data<<"$";
    preorder_traverse(root->left_child);
    preorder_traverse(root->right_child);
}
2.1.2 Iterative solution

The shilling root node is pushed onto the stack. Before the stack is empty, each time the top node is taken, the right child is pushed into the stack and the left child is pushed into the stack.
Insert picture description here
Insert picture description here

stack<Node*> Stack;
    Stack.push(root);
    while(!Stack.empty()){
    
    
        Node* top = Stack.top();
        cout<<top->data<<"&";
        Stack.pop();
        if(top->right_child)
            Stack.push(top->right_child);
        if(top->left_child)
            Stack.push(top->left_child);

2.2 In-order traversal

Visit the left child first, then the father, then the right child.

2.2.1 Recursive method

Insert picture description here
Insert picture description here

2.2.2 Direct successor under in-order traversal

When the node has a right child, then it is the node that the right subtree has always found to the left:
Insert picture description here
if the node does not have a right child, then the node as the right child has been looking for the parent from the upper left, and the last step is to go to the upper right:
Insert picture description here

Node* succ(){
    
    
        if(this->right_child){
    
     //有右孩子
            Node* r = this->right_child;
            while(r->left_child){
    
    
                r = r->left_child;
            }
            return r;
        }
        else{
    
     //只有左孩子
            Node* l = this;
            while(l->parent != NULL && l->parent->right_child == l){
    
     //向左上迈一步
                l = l->parent;
            }
            return l->parent;
        }
    }

2.3 Post-order traversal

Insert picture description here
Example: The expression tree is post-order traversal
Insert picture description here

2.4 Hierarchical traversal

Insert picture description here

example:
Insert picture description here

void level_traverse(Node* root){
    
     //树的先序遍历
    queue<Node*> Q;
    Q.push(root);
    while(!Q.empty()){
    
    
        Node* front = Q.front();
        cout<<front->data<<"*";
        Q.pop();
        if(front->left_child)
            Q.push(front->left_child);
        if(front->right_child)
            Q.push(front->right_child);
    }
}

3. Binary tree reconstruction

3.1 [Preorder| Next Order] + Middle Order

Insert picture description here
Leetcode: Rebuild the binary tree https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/

class Solution {
    
    
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
    
    
        if(preorder.size() == 0) //别忘记递归停止条件
            return NULL;
        if(preorder.size() == 1) {
    
    
            TreeNode* root = new TreeNode(preorder[0]);
            return root;
        }
        vector<int> preorder_left; //左子树的先序遍历
        vector<int> preorder_right; //右子树的先序遍历
        vector<int> inorder_left; //左子树的中序遍历
        vector<int> inorder_right; //右子树的中序遍历
        int mid = preorder[0];
        TreeNode* root = new TreeNode(mid);
        int mid_pos; //root在中序遍历的位置
        for(int i = 0;i < inorder.size(); i++){
    
    
            if(inorder[i] == mid){
    
    
                mid_pos = i;
                break;
            }
        }
        int left_len = mid_pos;
        for(int i=1;i<1+left_len;i++)
            preorder_left.push_back(preorder[i]);
        for(int i = 1+left_len; i<preorder.size();i++)
            preorder_right.push_back(preorder[i]);
        for(int i = 0;i<left_len;i++)
            inorder_left.push_back(inorder[i]);
        for(int i= left_len + 1;i<inorder.size();i++)
            inorder_right.push_back(inorder[i]);

        TreeNode* left_tree = buildTree(preorder_left,inorder_left);
        TreeNode* right_tree = buildTree(preorder_right,inorder_right);
        root->left = left_tree;
        root->right = right_tree;
        return root;

    }
};

Guess you like

Origin blog.csdn.net/weixin_41332009/article/details/114767306