非递归访问一颗二叉树【C++】

本文详细介绍了如何使用非递归方法遍历二叉树,包括前序、中序和后序遍历,通过栈的数据结构实现了对每个节点的访问策略。

非递归访问一颗二叉树:

1.左路节点

2.左路节点的右子树

3.子问题 访问右树

144. 二叉树的前序遍历 - 力扣(LeetCode)

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        TreeNode* cur = root;
        vector<int> v;
        while(cur||!st.empty())
        {
            //开始访问一棵树
            //1.左路节点
            //2.左路节点的右子树
            while(cur)
            {
                v.push_back(cur->val);
                st.push(cur);
                cur = cur->left;
            }
            //开始访问右子树
            TreeNode* top = st.top();
            st.pop();
            //子问题访问右树
            cur=top->right;
        }
        return v;
    }
};

94. 二叉树的中序遍历 - 力扣(LeetCode)

与上述思路相同。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> v;
        stack<TreeNode*> st;
        TreeNode* cur = root;
        while(cur||!st.empty())
        {
            //左路节点
            while(cur)
            {
                st.push(cur);
                cur = cur->left;
            }
            //栈里面取到左路节点,左路节点他左子树访问完了
            TreeNode* top = st.top();
            st.pop();
            v.push_back(top->val);
            //访问左路节点右子树 -- 子问题
            cur = top->right;
        }
        return v;
    }
};

145. 二叉树的后序遍历 - 力扣(LeetCode) 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        stack <TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        TreeNode* prev = NULL;
        while(cur||!st.empty())
        {
            //1.左路节点
            while(cur)
            {
                st.push(cur);
                cur = cur->left;
            }
            ///栈里面取到左路节点。左路节点他左子树访问完了。
            TreeNode* top = st.top();
            //1.右为空,或者右子树已经访问过了(上一个访问的节点是右子树的根),可以访问根节点
            if(top->right == nullptr||top->right == prev)
            {
                v.push_back(top->val);
                st.pop();
                prev = top;
            }
            else
            {
                //访问左路节点右子树 -- 子问题
                cur = top->right;
            }
        }
        return v;
    }
};

### 构建二叉树的方法 在 C++ 中实现二叉树的构建可以采用多种方式,具体取决于输入的形式以及需求。以下是基于先序遍历递归构建二叉树的方式[^1]: ```cpp #include <iostream> using namespace std; // 定义二叉树节点结构 struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; TreeNode* createTree() { int value; cin >> value; // 输入节点值 if (value == -1) { // 使用-1表示空节点 return nullptr; } TreeNode* root = new TreeNode(value); // 创建当前节点 root->left = createTree(); // 递归创建左子树 root->right = createTree(); // 递归创建右子树 return root; } ``` 上述代码展示了如何通过用户输入来递归地构建一棵二叉树。如果需要更复杂的构建逻辑,比如根据前序和中序序列非递归地构建二叉树,则可参考以下方法[^2]。 #### 非递归构建二叉树(基于前序和中序) 假设已知前序序列 `preOrder` 和中序序列 `inOrder`,则可通过迭代法完成二叉树的构建: ```cpp #include <vector> #include <unordered_map> TreeNode* buildTree(vector<int>& preOrder, vector<int>& inOrder) { if (preOrder.empty()) return nullptr; unordered_map<int, int> indexMap; // 记录中序序列中各元素的位置 for (int i = 0; i < inOrder.size(); ++i) { indexMap[inOrder[i]] = i; } stack<TreeNode*> s; TreeNode* root = new TreeNode(preOrder[0]); s.push(root); int inorderIndex = 0; for (int i = 1; i < preOrder.size(); ++i) { int preorderVal = preOrder[i]; TreeNode* node = new TreeNode(preorderVal); if (!s.empty() && s.top()->val == inOrder[inorderIndex]) { while (!s.empty() && s.top()->val == inOrder[inorderIndex]) { TreeNode* top = s.top(); s.pop(); inorderIndex++; } if (!s.empty()) { s.top()->right = node; } else { s.push(node); } } else { s.top()->left = node; } s.push(node); } return root; } ``` 此代码片段实现了利用前序和中序序列非递归地构建二叉树的功能。它借助栈保存中间状态并逐步恢复树结构。 --- ### 关于二叉树的重要性 二叉树作为一种重要的数据结构,在计算机科学领域具有广泛应用价值。其核心特性在于每个节点最多有两个子节点,并且能够方便地表达层次关系[^3]。此外,对于任意 N 个节点组成的树而言,必然存在 N−1 条边连接这些节点[^4]。 --- ### 输出与验证 为了验证所构建的二叉树是否正确,通常会对其进行各种类型的遍历操作,例如先序、中序、后序或层序遍历[^5]。下面是一个简单的先序遍历函数示例: ```cpp void preorderTraversal(TreeNode* root) { if (root == nullptr) return; cout << root->val << " "; // 处理根节点 preorderTraversal(root->left); // 左子树 preorderTraversal(root->right); // 右子树 } ``` 调用该函数即可按顺序输出整棵树的内容。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值