在C++中,对n叉树(也叫n叉树、多叉树)进行后序遍历,通常有两种常见的方法实现:递归方法和迭代方法。
- 递归方法
递归方法是最直观的,它通过递归调用自身来访问每个节点的子节点。
首先,定义n叉树的节点结构:
#include <iostream>
#include <vector>
class Node {
public:
int val;
std::vector<Node*> children;
Node() {}
Node(int _val) {
val = _val;
}
Node(int _val, std::vector<Node*> _children) {
val = _val;
children = _children;
}
};
然后,实现后序遍历的递归函数:
void postorder(Node* root) {
if (root == nullptr) return;
for (Node* child : root->children) {
postorder(child); // 先遍历所有子节点
}
std::cout << root->val << " "; // 然后访问根节点
}
- 迭代方法
迭代方法通常使用栈来实现,因为它可以避免递归可能带来的栈溢出问题。
首先,定义一个辅助结构来存储节点和访问状态(是否已访问子节点):
struct TreeNodeInfo {
Node* node;
bool visitedChildren; // 是否已访问子节点
};
然后,实现后序遍历的迭代函数:
void postorderIterative(Node* root) {
if (root == nullptr) return;
std::stack<TreeNodeInfo> stack;
stack.push({root, false}); // 根节点入栈,子节点未访问
while (!stack.empty()) {
TreeNodeInfo top = stack.top();
if (!top.visitedChildren) { // 如果未访问子节点,先访问子节点
for (Node* child : top.node->children) { // 反向遍历可以保证左子树先被访问(但不是必须的)
stack.push({child, false}); // 子节点入栈,子节点未访问状态
}
stack.top().visitedChildren = true; // 标记当前节点子节点已访问
} else { // 如果已访问子节点,访问当前节点并弹出栈
std::cout << top.node->val << " "; // 访问当前节点值
stack.pop(); // 弹出当前节点信息
}
}
}
使用示例:
int main() {
// 构建一个简单的n叉树进行测试
Node* root = new Node(1);
root->children.push_back(new Node(3));
root->children.push_back(new Node(2));
root->children.push_back(new Node(4));
root->children[0]->children.push_back(new Node(5));
root->children[0]->children.push_back(new Node(6));
// 使用递归方法进行后序遍历:
std::cout << "Postorder (recursive): ";
postorder(root); // 应输出:5 6 3 4 2 1
std::cout << std::endl;
// 使用迭代方法进行后序遍历:
std::cout << "Postorder (iterative): ";
postorderIterative(root); // 应输出:5 6 3 4 2 1
std::cout << std::endl;
return 0;
}
这样,你就可以在后序遍历n叉树时选择使用递归或迭代方法了。