二叉树相关

1.二叉树基础

1)定义

struct TreeNode{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int val) : val(val),left(nullptr),right(nullptr){ }
};
2.前、中、后序的递归遍历

递归算法的三个要素:
1)确定递归函数的参数和返回值
2)确定终止条件
3)确定单层递归的逻辑

前序递归遍历

class solution{
    public:
        void traversal(TreeNode* cur, vector<int>& vec){
            if (cur==NULL) return;
            vec.push_back(cur->val);//根
            traversal(cur->left,vec);
            traversal(cur->right,vec);
        }
        vector<int> preorderTraversal(TreeNode* root){
            vector<int> result;
            traversal(root,result);
            return result;
        }
}

中序遍历

void traversal(TreeNode* cur, vector<int>& vec){
    if(cur == NULL) return;//终止条件
    //单层循环
    traversal(cur->left,vec);
    vec.push_back(cur->val);
    traversal(cur->right,vec);
}

后序遍历

void traversal(TreeNode* cur,vector<int>& vec){
    if(cur==NULL) return;
    traversal(cur->left,vec);
    traversal(cur->right,vec);
    vec.push_back(cur->val);
}

递归的实现就是,每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈,然后在结束本层递归操作之后,从栈顶弹出下一次递归的各项参数。

3.前中后序迭代遍历

前序遍历
根-》左-》右
先将根节点入栈,然后再将右孩子加入栈,最后将左孩子加入栈(先进后出)

class Solution{
public:
    vector<int> preorderTraversal(TreeNode* root){
        stack<TreeNode*> st;
        vector<int> result;
        if(root==NULL) return result;
        st.push(root);
        while(!st.empty()){
            TreeNode* node = st.top();
            st.pop();
            result.push_back(node->val);
            if(node->right) st.push(node->right);
            if(node->left) st.push(node->left);
        }
        return result;
    }
};

中序遍历

class Solution{
public:
    vector<int> inorderTraversal(TreeNode* root){
        vector<int> result;
        stack<TreeNode*> st;
        TreeNode* cur = root;
        while(cur!=NULL || !st.empty()){
            if(cur!=NULL){
                //指针访问节点并访问到底层
                st.push(cur)
                cur = cur->next;  //左
            }else{
                //从栈里弹出的数据就是要处理的
                cur = st.top();
                st.pop();
                result.push_back(cur->val); //中
                cur = cur->right; //右
            }
        }
        return result;
        
    }
}

后序迭代遍历
前序,根左右-》(调整代码左右顺序)-》根右左-》反转result数组-》左右根,后序
代码实现

class Sulution{
public:
    vector<int> postorderTraversal(TreeNode* root){
        stack<TreeNode*> st;
        vector<int> result;
        if(root==NULL) return result;
        st.push(root);
        while(!st.empty()){
            TreeNode* node = st.top();
            st.pop();
            result.push_back(node->val);
            if(node->left) st.push(node->left);
            if(node->right) st.push(node->right);
        }
        reverse(result.begin(),result.end());
        return result;
    }
};
4.前中后统一迭代法

使用迭代法时,主要存在使用栈无法解决访问节点和处理节点不一致的问题。
要访问的节点放入栈,将要处理的节点也放入栈但是要做标记,即将要处理的节点放入栈之后,紧接着放入一个空指针作为标记。这种方法也叫标记法。
将访问的节点直接加入了栈,如果是要处理的节点,则后面放入一个空节点,只有空节点弹出的时候,才将下一个节点放入结果集。

使用迭代法实现中序遍历

class Solution{
public:
    vector<int> inorderTraversal(TreeNode* root){
        vector<int> result;
        stack<TreeNode*> st;
        if(root!=NULL) st.push(root);
        while(!st.empty()){
            TreeNode* node = st.top();
            if(node!=NULL){
                //弹出该节点,避免重复操作,下面再将右、中、左节点添加到栈中
                st.pop();
                if(node->right) st.push(node->right);
                st.push(node);
                st.push(NULL);
                if(node->right) st.push(node->left);
            }else{//遇到空节点,才进行操作,将下一个节点放入结果集
                st.pop();//弹出空节点
                node = st.top();//栈中因素
                st.pop();
                result.push_back(node->val);
             }
        }
        return result;       
    }
}

使用迭代法实现前序遍历

class Solution{
public:
    vector<int> inorderTraversal(TreeNode* root){
        vector<int> result;
        stack<TreeNode*> st;
        if(root!=NULL) st.push(root);
        while(!st.empty()){
            TreeNode* node = st.top();
            if(node!=NULL){
                //弹出该节点,避免重复操作,下面再将右,左,根节点添加到栈中
                st.pop();
                if(node->right) st.push(node->right); 
                if(node->right) st.push(node->left);
                st.push(node);
                st.push(NULL);
            }else{//遇到空节点,才进行操作,将下一个节点放入结果集
                st.pop();//弹出空节点
                node = st.top();//栈中因素
                st.pop();
                result.push_back(node->val);
             }
        }
        return result;       
    }
}

使用迭代法实现后序遍历

class Solution{
public:
    vector<int> inorderTraversal(TreeNode* root){
        vector<int> result;
        stack<TreeNode*> st;
        if(root!=NULL) st.push(root);
        while(!st.empty()){
            TreeNode* node = st.top();
            if(node!=NULL){
                //弹出该节点,避免重复操作,下面再将根,右,左节点添加到栈中
                st.pop();
                st.push(node);
                st.push(NULL);
                if(node->right) st.push(node->right); 
                if(node->right) st.push(node->left);
            }else{//遇到空节点,才进行操作,将下一个节点放入结果集
                st.pop();//弹出空节点
                node = st.top();//栈中因素
                st.pop();
                result.push_back(node->val);
             }
        }
        return result;       
    }
}
5.层序遍历

层序遍历用队列实现

class Solution{
public:
    vector<vector<int>> levelOrder(TreeNode* root){
        queue<TreeNode*> que;
        if(root!=NULL) que.push(root);
        while(!que.empty()){
            int size = que.size();
            vector<int> vec;
            for(int i =0; i< size;i++){
                TreeNode* node = que.front();
                que.pop();
                vec.push_back(node->val);
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
            result.push_back(vec);
        }
        return result;
    }
};

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值