• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

第13天-代码随想录刷题训练-第六章 二叉树和迭代 ● 递归遍历 ● 迭代遍历 ● 统一迭代

武飞扬头像
陈大头啊呀
帮助1

递归三要素

  1. 确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。

  2. 确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。

  3. 确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。

LeetCode链接
144.二叉树的前序遍历
145.二叉树的后序遍历
94.二叉树的中序遍历

1.递归遍历二叉树

  • 前中后序 递归遍历二叉树
class Solution {
public:	
	// 前序
    void preOrder(TreeNode* node, vector<int> &result){
        if(node==NULL) return;

        result.push_back(node->val);
        preOrder(node->left, result);
        preOrder(node->right, result);
    }

    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        preOrder(root, result);

        return result;
    }
    
    // 中序
    void inOrder(TreeNode* node, vector<int> &result){
		if(node==NULL) return;
		inOrder(node->left, result);
		result.push_back(node->val);
		inOrder(node->right, result);
    }	
    
	// 后序
  void postOrder(TreeNode* node, vector<int> &result){
       if(node==NULL) return;
       postOrder(node->left, result);
       postOrder(node->right, result);
       result.push_back(node->val);
    }
};
学新通

2.迭代遍历二叉树

  • 遍历时应该注意对空节点的判断
  • 迭代遍历注意中序和前后序不同
  • 前序遍历:使用栈,中左右的顺序,因此遍历的时候先将根节点压入栈,然后while循环 弹出后将按照右左节点的顺序弹出
  • 后续遍历:和前序遍历类似,前序遍历先弹出中节点,然后修改为先压左节点再压入右节点,这样遍历出来的节点顺序是中右左,而后续遍历时左右中,将修改后的前序遍历输出反转
  • 中序遍历:使用遍历节点,从根节点开始一直向左访问,知道遇见空,弹出栈顶后,将右节点再压入栈中
// 前序遍历
vector<int> preorderTraversal(TreeNode* root) {
       vector<int> result;
       stack<TreeNode*> st;    
       if(root != NULL) st.push(root);
       else return result;

       while(!st.empty()){
           TreeNode* topNode = st.top();
           st.pop();
           result.push_back(topNode->val);

           // 忘了判断节点是否为空
           if(topNode->right != NULL) st.push(topNode->right);
           if(topNode->left != NULL) st.push(topNode->left);
       }

       return result;
  }
 	
 // 中序遍历
vector<int> inorderTraversal(TreeNode* root) {
    vector<int> result;
    stack<TreeNode*> st;
    if(root == NULL) return result;

    TreeNode* cur = root;
    while(cur!=NULL || !st.empty()){
        if(cur!=NULL){
            st.push(cur);                   // 左
            cur = cur->left;
        }else{
            cur = st.top();
            st.pop();
            result.push_back(cur->val);     // 中
            cur = cur->right;               // 右
        }
    }

    return result;
}

// 后序遍历
vector<int> postorderTraversal(TreeNode* root) {
    vector<int> result;
    stack<TreeNode*> st;
    if(root==NULL) return result;

    st.push(root);

    while(!st.empty()){
        TreeNode* topNode = st.top();
        st.pop();
        result.push_back(topNode->val);
        if(topNode->left != NULL) st.push(topNode->left);
        if(topNode->right != NULL) st.push(topNode->right);
    }
    reverse(result.begin(), result.end());

    return result;
}
学新通

3. 统一迭代法

  • 中序遍历:在每一个遍历到但是没有添加到结果集的中间节点后添加一个空元素
    // 统一迭代法
    vector<int> inorderTraversal(TreeNode* root){
        vector<int> result;
        stack<TreeNode*> st;
        if(root == NULL) return result;
        TreeNode* cur = root;
        st.push(root);
        while(!st.empty()){
            cur = st.top();
            if(cur != NULL){
                st.pop();
                if(cur->right) st.push(cur->right);
                
                st.push(cur);
                st.push(NULL);      // 遍历的每个中间节点后都会添加一个空节点,

                if(cur->right) st.push(cur->left); 
            }else{
                st.pop();
                cur = st.top(); // 中间节点
                st.pop();
                result.push_back(st->val);
            } 
        }
    }

vector<int> preorderTraversal(TreeNode* root) {
    vector<int> result;
    stack<TreeNode*> st;  
    if(root==NULL) return result;

    TreeNode* cur = root;
    st.push(root);

    while(!st.empty()){
        cur = st.top();
        if(cur != NULL){
            st.pop();
            if(cur->right) st.push(cur->right);
            if(cur->left) st.push(cur->left);
            st.push(cur);
            st.push(NULL);
        }else{
            st.pop();
            cur = st.top();
            st.pop();
            result.push_back(cur->val);
        }
    }

    return result;
}

vector<int> postorderTraversal(TreeNode* root) {
    vector<int> result;
    stack<TreeNode*> st;
    if(root==NULL) return result;
    st.push(root);
    TreeNode* cur = root;
    while(!st.empty()){
        cur = st.top();
        if(cur != NULL){
            st.push(NULL);
            if(cur->right) st.push(cur->right);
            if(cur->left) st.push(cur->left);
        }else{
            st.pop();
            cur = st.top();
            result.push_back(cur->val);
            st.pop();
        }
    }

    return result;
}
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggiakb
系列文章
更多 icon
同类精品
更多 icon
继续加载