文章目录
主要内容
在C++中,使用栈来实现二叉树的前序、中序和后序遍历是一种非递归的方法。下面是这三种遍历方式的实现示例:
首先,定义二叉树节点的结构体:
#include <iostream>
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
- 前序遍历(根 -> 左 -> 右)
void preorderTraversal(TreeNode* root) {
if (root == nullptr) return; // 如果根节点为空,则直接返回
std::stack<TreeNode*> stack; // 创建一个栈来存储节点
stack.push(root); // 将根节点压入栈
while (!stack.empty()) { // 当栈不为空时循环
TreeNode* node = stack.top(); // 取出栈顶元素
stack.pop(); // 弹出栈顶元素
std::cout << node->val << " "; // 访问当前节点
// 先压入右子节点,再压入左子节点(因为栈是后进先出的结构)
if (node->right) stack.push(node->right);
if (node->left) stack.push(node->left);
}
}
- 中序遍历(左 -> 根 -> 右)
void inorderTraversal(TreeNode* root) {
std::stack<TreeNode*> stack; // 创建一个栈来存储节点
TreeNode* current = root; // 从根节点开始
while (current != nullptr || !stack.empty()) { // 当当前节点不为空或栈不为空时循环
while (current != nullptr) { // 不断向左子树深入
stack.push(current); // 将当前节点压入栈
current = current->left; // 移动到左子节点
}
current = stack.top(); // 取出栈顶元素
stack.pop(); // 弹出栈顶元素
std::cout << current->val << " "; // 访问当前节点
current = current->right; // 移动到右子节点
}
}
- 后序遍历(左 -> 右 -> 根)
后序遍历稍微复杂一些,因为需要确保节点的右子节点在左子节点之后且在根节点之前被访问。
void postorderTraversal(TreeNode* root) {
if (root == nullptr) return; // 如果根节点为空,则直接返回
std::stack<TreeNode*> stack; // 创建一个栈来存储节点
TreeNode* lastVisited = nullptr; // 记录最近访问过的节点
TreeNode* current = root; // 从根节点开始
while (current != nullptr || !stack.empty()) { // 当当前节点不为空或栈不为空时循环
while (current != nullptr) { // 不断向左子树深入
stack.push(current); // 将当前节点压入栈
current = current->left; // 移动到左子节点
}
TreeNode* topNode = stack.top(); // 查看栈顶元素
// 如果右子节点存在且未被访问过,则先访问右子节点
if (topNode->right != nullptr && lastVisited != topNode->right) {
current = topNode->right;
} else {
std::cout << topNode->val << " "; // 访问当前节点
lastVisited = topNode; // 更新最近访问过的节点
stack.pop(); // 弹出栈顶元素
}
}
}