1 介绍
非递归实现二叉树的后序遍历可以通过使用栈来实现。后序遍历的顺序是左子树 -> 右子树 -> 根节点。
基本思路是利用两个栈。一个栈用于辅助遍历,另一个栈用于存储遍历的结果。具体步骤如下:
- 首先将根节点入栈。
- 循环执行以下操作:
从辅助栈中弹出一个节点,将其值压入结果栈。
如果该节点有左孩子,则将左孩子压入辅助栈。
如果该节点有右孩子,则将右孩子压入辅助栈。 - 当辅助栈为空时,遍历结束。此时结果栈中的元素即为后序遍历的结果。
下面是一个示例代码:
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
// 二叉树节点定义
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
vector<int> postorderTraversal(TreeNode* root) {
vector<int> result;
if (!root) return result;
stack<TreeNode*> stack1, stack2;
stack1.push(root);
while (!stack1.empty()) {
TreeNode* node = stack1.top();
stack1.pop();
stack2.push(node);
if (node->left) stack1.push(node->left);
if (node->right) stack1.push(node->right);
}
// 将结果栈中的元素弹出,即得到后序遍历的结果
while (!stack2.empty()) {
result.push_back(stack2.top()->val);
stack2.pop();
}
return result;
}
int main() {
// 创建一棵二叉树
TreeNode* root = new TreeNode(1);
root->left = new TreeNode(2);
root->right = new TreeNode(3);
root->left->left = new TreeNode(4);
root->left->right = new TreeNode(5);
root->right->left = new TreeNode(6);
root->right->right = new TreeNode(7);
// 后序遍历
vector<int> result = postorderTraversal(root);
// 输出结果
cout << "后序遍历结果为:";
for (int val : result) {
cout << val << " ";
}
cout << endl;
return 0;
}
2 训练
题目1:145二叉树的后续遍历
C++代码如下,
方法1:递归实现
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
if (root == nullptr) return {};
//递归实现后续遍历:左右根
vector<int> res;
if (root->left != nullptr) {
vector<int> t = postorderTraversal(root->left);
res.insert(res.end(), t.begin(), t.end());
}
if (root->right != nullptr) {
vector<int> t = postorderTraversal(root->right);
res.insert(res.end(), t.begin(), t.end());
}
res.emplace_back(root->val);
return res;
}
};
方法2:非递归实现
/**
* 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) {
vector<int> res;
if (root == nullptr) return res;
//非递归实现后续遍历:左右根
stack<TreeNode*> stk1, stk2;
stk1.push(root);
while (!stk1.empty()) {
TreeNode* node = stk1.top();
stk2.push(node);
stk1.pop();
if (node->left != nullptr) stk1.push(node->left);
if (node->right != nullptr) stk1.push(node->right);
}
while (!stk2.empty()) {
TreeNode* node = stk2.top();
res.emplace_back(node->val);
stk2.pop();
}
return res;
}
};
题目2:144二叉树的前序遍历
C++代码如下,
方法1:递归实现
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
if (root == nullptr) return res;
res.emplace_back(root->val);
if (root->left != nullptr) {
vector<int> t = preorderTraversal(root->left);
res.insert(res.end(), t.begin(), t.end());
}
if (root->right != nullptr) {
vector<int> t = preorderTraversal(root->right);
res.insert(res.end(), t.begin(), t.end());
}
return res;
}
};
方法2:非递归实现
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
if (root == nullptr) return res;
stack<TreeNode*> stk1;
stk1.push(root);
while (!stk1.empty()) {
TreeNode* node = stk1.top();
stk1.pop();
res.emplace_back(node->val);
if (node->right != nullptr) stk1.push(node->right);
if (node->left != nullptr) stk1.push(node->left);
}
return res;
}
};
题目3:94二叉树的中序遍历
C++代码如下,
方法1:递归实现
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
if (root == nullptr) return res;
if (root->left != nullptr) {
vector<int> t = inorderTraversal(root->left);
res.insert(res.end(), t.begin(), t.end());
}
res.emplace_back(root->val);
if (root->right != nullptr) {
vector<int> t = inorderTraversal(root->right);
res.insert(res.end(), t.begin(), t.end());
}
return res;
}
};
方法2:非递归实现
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
if (root == nullptr) return res;
stack<TreeNode*> stk1;
TreeNode* curr = root;
while (curr != nullptr || !stk1.empty()) {
//将当前结点的所有左子结点入栈
while (curr != nullptr) {
stk1.push(curr);
curr = curr->left;
}
//弹出栈顶结点,将其值存储到结果中
curr = stk1.top();
stk1.pop();
res.emplace_back(curr->val);
//如果弹出的结点有右子结点,则将右子结点作为当前结点,继续遍历其左子结点
curr = curr->right;
}
return res;
}
};