数据结构THU2018 - 树

1. 树的节点定义

在这里插入图片描述
在这里插入图片描述

每个节点都指向一个parent(根节点除外),每个节点可以有一个左孩子,一个右孩子。

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. 树的遍历

2.1 先序遍历

先访问根节点,再访问左孩子,最后访问右孩子:
在这里插入图片描述

2.1.1 递归解法
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 迭代解法

先令根节点入栈。在栈空之前,每次取top节点,使右孩子入栈、左孩子入栈。
在这里插入图片描述
在这里插入图片描述

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 中序遍历

先访问左孩子,然后访问父亲,然后访问右孩子。

2.2.1 递归方法

在这里插入图片描述
在这里插入图片描述

2.2.2 中序遍历下的直接后继

当该节点有右孩子,那么就是右边子树一直向左找到的那个节点:
在这里插入图片描述
如果该节点没有右孩子,那么就是该节点作为右孩子一直向左上找parent,最后一步再向右上走一步:
在这里插入图片描述

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 后序遍历

在这里插入图片描述
举例:表达式树就是后序遍历
在这里插入图片描述

2.4 层次遍历

在这里插入图片描述

例子:
在这里插入图片描述

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. 二叉树重建

3.1 [前序 | 后序] + 中序

在这里插入图片描述
Leetcode: 重建二叉树 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;

    }
};

猜你喜欢

转载自blog.csdn.net/weixin_41332009/article/details/114767306