您的位置:

详解Postorder:从遍历到求值

一、postorder函数

void postorder(node* root) 
{ 
    if (root == NULL) 
        return; 
    postorder(root->left); 
    postorder(root->right); 
    cout << root->data << " "; 
} 

postorder函数是二叉树遍历的一种方式。它遍历整棵树,先访问左子树,然后访问右子树,最后访问根节点。对于一棵二叉树,不同的遍历方式得到的序列是不一样的。postorder的特点是在访问根节点之前,先将左右子树遍历完。一个节点的遍历顺序为:首先访问左子树,然后访问右子树,最后访问根节点。

接下来是一个示例,我们创建一个二叉树并用postorder遍历它:

// 创建二叉树 
node* createNode(int data) 
{ 
    node* newNode = new node(); 
    if (!newNode) { 
        cout << "无法分配内存空间" << endl; 
        return NULL; 
    } 
    newNode->data = data; 
    newNode->left = newNode->right = NULL; 
    return newNode; 
} 

node* createTree() 
{ 
    node* root = createNode(1); 
    root->left = createNode(2); 
    root->right = createNode(3); 
    root->left->left = createNode(4); 
    root->left->right = createNode(5); 
    root->right->left = createNode(6); 
    root->right->right = createNode(7); 
    return root; 
} 

int main() 
{ 
    node* root = createTree(); 
    cout << "postorder序列: "; 
    postorder(root); 
    return 0; 
} 

输出结果为:4 5 2 6 7 3 1。这是因为我们遍历了对应的二叉树,先访问了左子树4和5,再访问2,然后访问右子树,先访问6和7,最后访问1。

二、postorder遍历二叉树

我们刚才已经对postorder的遍历过程进行了详细的探讨,现在我们来看一个更加实际的例子,如何使用postorder遍历二叉树。

// 使用postorder遍历二叉树 
void postorderTraversal(node* root) 
{ 
    stack s1, s2; 
    s1.push(root); 
    while (!s1.empty()) { 
        node* temp = s1.top(); 
        s1.pop(); 
        s2.push(temp); 
        if (temp->left) 
            s1.push(temp->left); 
        if (temp->right) 
            s1.push(temp->right); 
    } 
    while (!s2.empty()) { 
        node* temp = s2.top(); 
        s2.pop(); 
        cout << temp->data << " "; 
    } 
} 

  

这里我们使用了两个栈来辅助进行遍历。首先将根节点压入第一个栈s1中,然后在s1不为空的情况下,进行以下操作:每次取出s1栈顶元素temp,将其压入第二个栈s2中,然后先将左子树压入s1,再将右子树压入s1。这样可以保证最后从s2中输出的顺序是postorder。

三、postordereval

除了遍历外,postorder还可以用来求解一些问题,例如表达式树的求值。下面是一个表达式树的例子:

// 创建表达式树 
node* createExpressionTree(string postfix) 
{ 
    stack s; 
    for (int i = 0; i < postfix.length(); i++) { 
        if (isdigit(postfix[i])) { 
            node* temp = createNode(postfix[i] - '0'); 
            s.push(temp); 
        } 
        else { 
            node* temp = createNode(postfix[i]); 
            temp->right = s.top(); 
            s.pop(); 
            temp->left = s.top(); 
            s.pop(); 
            s.push(temp); 
        } 
    } 
    return s.top(); 
} 

  

这里我们是用postfix表达式来创建一个表达式树,其表达式如下所示:

string postfix = "23*5+"; 

postorder提供了一种很自然的求值方式,求解表达式树的值其实就是一棵树的后序遍历。

// 计算表达式树的值 
int postordereval(node* root) 
{ 
    if (!root) 
        return 0; 
    int left = postordereval(root->left); 
    int right = postordereval(root->right); 

    if (!isdigit(root->data)) { 
        switch (root->data) { 
        case '+': 
            return left + right; 
        case '-': 
            return left - right; 
        case '*': 
            return left * right; 
        case '/': 
            return left / right; 
        } 
    } 
    return root->data; 
} 

这里我们使用递归的方法,先计算左子树和右子树的值,然后利用根节点的符号进行计算,并返回结果。最终得到的结果就是表达式树的值。

四、postorder怎么传二叉树进去

我们在刚才的示例中已经展示了如何构建一个二叉树,这里我们进一步探讨如何将一个二叉树传入postorder函数。

// 定义二叉树节点 
struct node { 
    int data; 
    node* left; 
    node* right; 
}; 

// postorder遍历二叉树 
void postorder(node* root) 
{ 
    if (root == NULL) 
        return; 
    postorder(root->left); 
    postorder(root->right); 
    cout << root->data << " "; 
} 

// 主函数 
int main() 
{ 
    // 创建根节点 
    node* root = new node; 
    root->data = 1; 

    // 创建左子树 
    root->left = new node; 
    root->left->data = 2; 

    // 创建右子树 
    root->right = new node; 
    root->right->data = 3; 

    // 创建左子树的左子树和右子树 
    root->left->left = new node; 
    root->left->left->data = 4; 
    root->left->right = new node; 
    root->left->right->data = 5; 

    // 创建右子树的左子树和右子树 
    root->right->left = new node; 
    root->right->left->data = 6; 
    root->right->right = new node; 
    root->right->right->data = 7; 

    // postorder遍历二叉树 
    cout << "postorder序列: "; 
    postorder(root); 

    return 0; 
} 

我们可以通过逐个创建节点并设定每个节点的值和指针,来创建一棵二叉树,并将根节点root传入postorder函数中。这里可以根据自己的需求灵活设定节点值和指针,从而创建出不同形状和内容的二叉树。

五、postorder successor

postorder successor是指在postorder遍历中,对于当前节点,其后继节点是哪个节点。我们来看一个示例,如何求解一个二叉树的postorder successor:

// 找到node节点的postorder successor 
node* postorderSuccessor(node* root, node* nodeToFind) 
{ 
    stack s1, s2; 
    s1.push(root); 

    // 找到节点 
    while (!s1.empty()) { 
        node* temp = s1.top(); 
        s1.pop(); 

        if (temp->left) 
            s1.push(temp->left); 
        if (temp->right) 
            s1.push(temp->right); 

        if (temp == nodeToFind) 
            break; 
    } 

    // 找到后继节点 
    while (!s1.empty()) { 
        node* temp = s1.top(); 
        s1.pop(); 
        s2.push(temp); 
        if (!s1.empty() && s1.top()->right == temp) { 
            while (!s1.empty() && s1.top()->right == temp) { 
                temp = s1.top(); 
                s1.pop(); 
                s2.push(temp); 
            } 
        } 
    } 

    return s2.top(); 
} 

  

这里我们采用的方法是先遍历二叉树找到给定的节点nodeToFind,在栈s1中存储遍历过程中的节点。然后从栈s1中弹出节点,将其压入s2中,并判断是否存在后继节点。如果当前节点是最后一个节点或者其右子节点是上一个压入栈s1中的节点,说明当前节点的后继节点是上一个弹出栈s1的节点。最终返回栈s2中的top节点作为当前节点的后继节点。

结束语

Postorder作为二叉树遍历的一种方式,具有其特殊的特点和应用场景。通过对其定义、实现以及应用的探讨,相信读者已经掌握了postorder的基本用法并能根据自己的需求灵活运用。希望读者能够继续深入二叉树的学习,进一步探索其更为广泛的应用领域。

详解Postorder:从遍历到求值

2023-05-18
普通树的深度遍历c语言,树的层次遍历c语言

2023-01-04
深度优先遍历类似于二叉树的什么遍历

2023-05-20
c语言深度优先二叉树遍历,深度优先遍历类似于二叉树的层次遍历

本文目录一览: 1、急急急!求C语言的数据结构二叉树递归遍历程序! 2、C语言二叉树的遍历。 3、C语言数据结构“遍历二叉树” 4、二叉树的创建和遍历 急急急!求C语言的数据结构二叉树递归遍历程序!

2023-12-08
php实现二叉树前中后序遍历,求二叉树前序遍历

2022-11-29
二叉树层序遍历递归python(递归层次遍历二叉树)

2022-11-16
c语言层序遍历创建二叉树,二叉树的建立与遍历完整代码C语言

2022-11-23
python基础学习整理笔记,Python课堂笔记

2022-11-21
java遍历二叉树,java遍历二叉树代码

2023-01-03
java方法整理笔记(java总结)

2022-11-08
java遍历二叉树,java实现二叉树遍历

2023-01-05
java二叉树遍历,java二叉树遍历动画

2023-01-10
Python实现遍历树形结构的方法

2023-05-13
二叉树遍历java,二叉树遍历方式

2023-01-06
后序遍历二叉树的递归算法c语言,实现二叉树的后序遍历的非递归

2023-01-03
Java实现遍历

2023-05-11
二叉树的前序遍历c语言,二叉树前序遍历c语言代码

2022-11-25
java二叉树的建立和递归遍历(java二叉树的建立和递归遍

2022-11-09
层次遍历构建二叉树c语言,c语言二叉树的创建与遍历

2023-01-06
输出二叉树的层次遍历c语言,遍历二叉树C语言

2023-01-04