数据结构与算法之后序遍历

后序遍历是二叉树遍历的一种形式,它的遍历顺序是从左子树到右子树最后访问根节点。具体操作如下:

  1. 遍历当前节点的左子树
  2. 遍历当前节点的右子树
  3. 访问当前节点

在代码实现中,后序遍历可以使用递归或者栈来实现。递归实现比较简单,栈实现则需要使用一个辅助栈来记录当前节点的状态,具体实现如下:

  1. 将根节点入栈
  2. 当栈不为空时,取出栈顶元素
  3. 如果栈顶节点的左子树和右子树都已经访问过,则访问当前节点,并将其出栈
  4. 如果栈顶节点的左子树或者右子树还未访问,则将其左子树和右子树先入栈(先入右子树再入左子树)

以下是一个用递归实现的后序遍历的示例代码:

class Solution {
public:
    vector<int> res;

    vector<int> postorderTraversal(TreeNode* root) {
        if (!root) return res;
        postorderTraversal(root->left);
        postorderTraversal(root->right);
        res.push_back(root->val);
        return res;
    }
};

以下是一个用栈实现的后序遍历的示例代码:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        if (!root) return res;

        stack<pair<TreeNode*, bool>> stk; // <节点,是否访问过该节点的左右子树>
        stk.push({root, false});

        while (!stk.empty()) {
            auto [node, visited] = stk.top();
            stk.pop();
            if (visited) {
                res.push_back(node->val);
            } else {
                stk.push({node, true});
                if (node->right) {
                    stk.push({node->right, false});
                }
                if (node->left) {
                    stk.push({node->left, false});
                }
            }
        }

        return res;
    }
};

在这里插入图片描述

一、C 实现 后序遍历 及代码详解

后序遍历是二叉树的一种遍历方式,它的访问顺序是先访问左子树,再访问右子树,最后访问根节点。

在C语言中,可以通过递归或者非递归方式实现二叉树的后序遍历。

递归实现后序遍历的代码如下:

//定义二叉树结构体
typedef struct TreeNode{
    int val;
    struct TreeNode* left;
    struct TreeNode* right;
}TreeNode;

void postorderTraversal(TreeNode* root){
    if(root != NULL){
        postorderTraversal(root->left);   //递归遍历左子树
        postorderTraversal(root->right);  //递归遍历右子树
        printf("%d ", root->val);         //访问根节点
    }
}

上述代码中,先判断二叉树是否为空,如果不为空,则先递归遍历左子树,再递归遍历右子树,最后访问根节点。

非递归实现后序遍历的代码如下:

typedef struct TreeNode{
    int val;
    struct TreeNode* left;
    struct TreeNode* right;
}TreeNode;

typedef struct Stack{
    TreeNode** node_array;
    int top;
    int size;
}Stack;

void init(Stack* stack, int size){
    stack->node_array = (TreeNode**)malloc(sizeof(TreeNode*) * size);
    stack->top = -1;
    stack->size = size;
}

void push(Stack* stack, TreeNode* node){
    if(stack->top < stack->size - 1){
        stack->node_array[++(stack->top)] = node;
    }
}

TreeNode* pop(Stack* stack){
    if(stack->top != -1){
        return stack->node_array[(stack->top)--];
    }
    return NULL;
}

TreeNode* get(Stack* stack){
    if(stack->top != -1){
        return stack->node_array[stack->top];
    }
    return NULL;
}

int isEmpty(Stack* stack){
    return stack->top == -1;
}

void postorderTraversal(TreeNode* root){
    if(root == NULL) return;

    Stack stack1, stack2;
    init(&stack1, 100);
    init(&stack2, 100);

    push(&stack1, root);

    while(!isEmpty(&stack1)){
        TreeNode* node = pop(&stack1);
        push(&stack2, node);

        if(node->left != NULL){
            push(&stack1, node->left);
        }

        if(node->right != NULL){
            push(&stack1, node->right);
        }
    }

    while(!isEmpty(&stack2)){
        TreeNode* node = pop(&stack2);
        printf("%d ", node->val);
    }
}

上述代码中,先判断二叉树是否为空,如果不为空,则定义两个栈stack1和stack2,模拟后序遍历的过程。首先将根节点压入stack1中,然后将stack1中的节点依次出栈,并压入stack2中。如果当前节点有子节点,则先将右子节点压入stack1中,再将左子节点压入stack1中。最后依次将stack2中的节点出栈并访问。

在这里插入图片描述

二、C++ 实现 后序遍历 及代码详解

后序遍历(Postorder Traversal)是二叉树的一种遍历方式,也叫做后根遍历。在后序遍历中,我们先遍历一个节点的左子树,然后遍历其右子树,最后访问该节点本身。

下面是 C++ 实现后序遍历的代码,使用了递归方式实现:

#include <iostream>
using namespace std;

// 定义二叉树节点
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

// 后序遍历函数
void postorderTraversal(TreeNode* root) {
    if (root == NULL) {
        return;
    }
    postorderTraversal(root->left);   // 遍历左子树
    postorderTraversal(root->right);  // 遍历右子树
    cout << root->val << " ";         // 访问节点
}

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

    // 后序遍历
    cout << "Postorder Traversal: ";
    postorderTraversal(root);

    return 0;
}

上述代码中,我们首先定义了一个二叉树节点结构体 TreeNode,包含节点值和左右子树指针。然后实现了 postorderTraversal 函数,在其中使用递归方式实现后序遍历,先遍历左子树,再遍历右子树,最后访问节点本身。最后在 main 函数中创建了一个二叉树,并对其进行后序遍历。

该代码的输出结果为:

Postorder Traversal: 4 5 2 3 1

其中 4 5 2 3 1 就是后序遍历得到的节点序列。

在这里插入图片描述

三、Java 实现 后序遍历 及代码详解

后序遍历是二叉树遍历的一种方式。在后序遍历中,先遍历左子树,再遍历右子树,最后访问根节点。下面是 Java 实现后序遍历的代码:

public class Node {
    int val;
    Node left;
    Node right;

    public Node(int val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

public void postOrderTraversal(Node root) {
    if (root != null) {
        postOrderTraversal(root.left);
        postOrderTraversal(root.right);
        System.out.print(root.val + " ");
    }
}

代码中,首先定义了一个 Node 类表示二叉树节点。每个节点都包括一个值 val,以及指向左右子节点的指针 leftright

postOrderTraversal 方法用于遍历二叉树并输出每个节点的值。如果当前节点不为空,则先递归遍历左子树,再递归遍历右子树,最后输出当前节点的值。

在这个方法中,最终的遍历结果是按照后序遍历的顺序输出的。当然,如果需要将遍历结果保存下来,也可以将遍历的值存入一个列表或栈中。

在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值