![cover](https://img-blog.csdnimg.cn/758194da669348e3b9a2683fcd48c5cf.png)
数据结构与算法之后序遍历
数据结构与算法之后序遍历
后序遍历是二叉树遍历的一种形式,它的遍历顺序是从左子树到右子树最后访问根节点。具体操作如下:
- 遍历当前节点的左子树
- 遍历当前节点的右子树
- 访问当前节点
在代码实现中,后序遍历可以使用递归或者栈来实现。递归实现比较简单,栈实现则需要使用一个辅助栈来记录当前节点的状态,具体实现如下:
- 将根节点入栈
- 当栈不为空时,取出栈顶元素
- 如果栈顶节点的左子树和右子树都已经访问过,则访问当前节点,并将其出栈
- 如果栈顶节点的左子树或者右子树还未访问,则将其左子树和右子树先入栈(先入右子树再入左子树)
以下是一个用递归实现的后序遍历的示例代码:
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
,以及指向左右子节点的指针 left
和 right
。
postOrderTraversal
方法用于遍历二叉树并输出每个节点的值。如果当前节点不为空,则先递归遍历左子树,再递归遍历右子树,最后输出当前节点的值。
在这个方法中,最终的遍历结果是按照后序遍历的顺序输出的。当然,如果需要将遍历结果保存下来,也可以将遍历的值存入一个列表或栈中。
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)