0
点赞
收藏
分享

微信扫一扫

二叉树的非递归后序遍历

MaxWen 2024-06-07 阅读 8

二叉树的后序遍历是一种深度优先遍历算法,其遍历顺序为:左子树 -> 右子树 -> 根节点。非递归实现后序遍历通常使用一个辅助栈来模拟递归过程。

当然是一个C++二叉树非递归后序遍历算法:

#include <iostream>
#include <stack>

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

void PostorderTraversal(TreeNode* root) {
    if (!root) return;

    std::stack<TreeNode*> stack;
    TreeNode* current = root;
    TreeNode* lastVisited = nullptr;

    while (current != nullptr || !stack.empty()) {
        if (current != nullptr) {
            stack.push(current);
            current = current->left; // 先左子树
        }

        else {
            // 当current为nullptr且栈不为空时,处理栈顶元素
            current = stack.top();
            if (current->right != nullptr && current->right != lastVisited) {
                // 如果当前节点有右子树,且右子树未被访问
                current = current->right; // 转向右子树
            }

            else {
                // 当前节点的左右子树都已访问完毕
                stack.pop(); // 弹出当前节点
                std::cout << current->val << " "; // 打印当前节点的值
                lastVisited = current; // 更新lastVisited为当前节点
                current = nullptr; // 重置current,准备下一次循环
            }
        }
    }
}

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);

    std::cout << "Postorder traversal of the binary tree is: ";
    PostorderTraversal(root);

    // 释放分配的内存(实际应用中应更彻底地释放所有节点的内存)
    delete root->left->left;
    delete root->left->right;
    delete root->left;
    delete root->right;
    delete root;

    return 0;
}

这个算法的关键点是:

  1. 使用一个 std::stack 来存储待访问的节点。
  2. 使用一个 current 指针来遍历树,初始指向根节点。
  3. 使用一个 lastVisited 指针来记录上一个访问的节点,以便在后序遍历中正确地访问和打印节点。
  4. 循环继续,直到 current 为 nullptr 且栈为空。
  5. 在循环中,首先尝试访问左子树。
  6. 如果 current 为 nullptr,检查栈顶节点的右子树是否未被访问(即不是 lastVisited 节点),如果是,则访问右子树。
  7. 如果当前节点的右子树已经被访问,或者没有右子树,则从栈中弹出当前节点,打印它的值,并将 lastVisited 更新为当前节点。

这个算法避免了之前提到的逻辑问题,确保了每个节点只被访问一次,并且按照后序遍历的正确顺序(左 -> 右 -> 当前)来访问。同时,它还确保了在访问完节点后,将 current 设置为 nullptr,避免已经访问过的节点再次被处理。

举报

相关推荐

0 条评论