【C++】二叉树进阶面试题(下)

文章详细介绍了如何通过前序遍历、中序遍历和后序遍历构建二叉树,以及分别使用非递归迭代的方式实现这些遍历算法。每个部分都给出了题目分析和相应的C++代码示例。
摘要由CSDN通过智能技术生成

目录

6. 根据一棵树的前序遍历与中序遍历构造二叉树

题目

分析

代码

7. 根据一棵树的中序遍历与后序遍历构造二叉树

题目

分析

代码

8. 二叉树的前序遍历,非递归迭代实现 

题目

分析

代码

9. 二叉树中序遍历 ,非递归迭代实现

题目

分析

代码

10. 二叉树的后序遍历 ,非递归迭代实现

题目

分析

代码


6. 根据一棵树的前序遍历与中序遍历构造二叉树

题目

OJ链接

分析

前序遍历的第一个结点一定是根节点,根据根结点在中序结点的位置可以划分出根节点的左右结点范围,然后根据递归调用,不断地划分子树的左右结点,代码如下

代码

class Solution {
public:
    TreeNode* createTree(vector<int>& preorder, vector<int>& inorder,int& cur,int begin,int end)
    {
        if (begin > end)
            return nullptr;
        int root = begin;
        //寻找根节点在中序遍历的位置
        while (root <= end)
        {
            if (preorder[cur] == inorder[root])
                break;
            ++root;
        }
        TreeNode* ret = new TreeNode(preorder[cur++]);
        ret->left=createTree(preorder, inorder, cur, begin, root-1);
        ret->right=createTree(preorder, inorder, cur, root+1, end);
        return ret;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if (preorder.empty() || inorder.empty())
            return nullptr;
        int cur=0;
        int begin = 0;
        int end = inorder.size() - 1;
        return createTree(preorder, inorder,cur,begin,end);
    }
};

7. 根据一棵树的中序遍历与后序遍历构造二叉树

题目

OJ链接

分析

方法跟上一题类似,只是后续遍历的根节点要从最后一位找,并且向前遍历,同时要注意先找右子树再找左子树。

代码

class Solution {
public:
    TreeNode* createTree(vector<int>& postorder, vector<int>& inorder, int& cur, int begin, int end)
    {
        if (begin > end)
            return nullptr;
        int root = begin;
        while (root <= end)
        {
            if (postorder[cur] == inorder[root])
                break;
            ++root;
        }
        TreeNode* ret = new TreeNode(postorder[cur--]);

        ret->right = createTree(postorder, inorder, cur, root + 1, end);
        ret->left = createTree(postorder, inorder, cur, begin, root - 1);
        return ret;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if (postorder.empty() || inorder.empty())
            return nullptr;
        int cur = inorder.size() - 1;
        int begin = 0;
        int end = cur;
        return createTree(postorder, inorder, cur, begin, end);
    }
};

8. 二叉树的前序遍历,非递归迭代实现 

题目

OJ链接

分析

任意一个树我们都可以分为两部分:左路结点和左路结点的右子树,如下图

左路结点的右子树又可以分为新的左路结点和左路结点的右子树

通过这种思路,如下代码所示

代码

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        if (root == nullptr)
            return ans;
        TreeNode* cur = root;
        stack<TreeNode*> st;
        while (!st.empty()||cur)
        {
            //插入所有左路结点到栈中
            while (cur)
            {
                st.push(cur);
                ans.push_back(cur->val);
                cur = cur->left;
            }
            //对左路结点进行出栈,并将左路结点的右子树的根作为新的cur结点
            //下一层循环访问右子树的所有左路结点插入到栈中
            TreeNode* top = st.top();
            st.pop();
            cur = top->right;

        }
        return ans;
    }
};

9. 二叉树中序遍历 ,非递归迭代实现

题目

OJ链接

分析

将上一题的ans.push_back放到下面既可以完成

代码

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ans;
        if (root == nullptr)
            return ans;
        TreeNode* cur = root;
        stack<TreeNode*> st;
        while (!st.empty()||cur)
        {
            while (cur)
            {
                st.push(cur);

                cur = cur->left;
            }
            TreeNode* top = st.top();
            st.pop();
            ans.push_back(top->val);
            cur = top->right;

        }
        return ans;
    }
};

10. 二叉树的后序遍历 ,非递归迭代实现

题目

OJ链接

分析

因为是后序遍历,父亲结点最后插入,所以要判断右结点是否为空或者右结点是上一次访问过的结点

代码

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ans;
        if (root == nullptr)
            return ans;
        TreeNode* prenode = nullptr;
        TreeNode* cur = root;
        stack<TreeNode*> st;
        while (!st.empty() || cur) {
            while (cur) {
                st.push(cur);
                cur = cur->left;
            }
            TreeNode* top = st.top();

            if (top->right == nullptr || prenode == top->right) {
                st.pop();
                ans.push_back(top->val);
                prenode = top;
            } else {
                cur = top->right;
            }
        }
        return ans;
    }
};

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_hhc_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值