前中后序遍历(非递归)

这篇博客详细介绍了如何使用迭代法实现二叉树的前序、中序和后序遍历。对于前序遍历,压栈顺序为根、右、左,最后反转结果。后序遍历则是根、左、右的压栈顺序,同样需要反序输出。中序遍历通过不断左入栈,直到为空,然后出栈并访问,再压入右节点。

前序遍历和后续遍历
前序遍历的顺序是:根 左 右 ;压栈顺序就是根 右 左
后续遍历:左 右 根 ;可以通过根 右 左 的顺序遍历,最后反序得到;压栈顺序:根 左 右
中序遍历:注意根不能先入栈了,利用一个移动结点,在while内入栈,不断左 入栈,最后出栈 ,再压右

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

#
# 
# @param root TreeNode类 
# @return int整型一维数组
#
#先序遍历的实现根, 左, 右 需要先压入根,再将右压入,再压左,
#迭代法 ,先实现根 右 左 再reverse
class Solution:
    def postorderTraversal(self , root ):
        if root == None:
            return []
        stack = [root]
        result = []
        while stack:
            top = stack.pop()
            #将根的值压入结果
            result.append(top.val)
            #压入左,右,才能访问根,右,左
            if top.left:
                stack.append(top.left)
            if top.right:
                stack.append(top.right)
        #反序输出
        return result[::-1]

#迭代实现二叉树的先序遍历
#递归的就是用栈实现的
    def preorderTraversal(self, root):
        if not root:
            return []
        stack = [root]
        result = []
        while stack:
            top = stack.pop()
            result.append(top.val)
            if top.right:
                stack.append(top.right)
            if top.left:
                stack.append(top.left)
        
        return result

#中序遍历
    def inorderTraversal(self, root):
        if not root:
            return []
        stack = []
        p = root
        result = []
        while stack or p:
            while p:
                stack.append(p)
                p = p.left
            if stack:
                p = stack.pop()
                result.append(p.val)
                p = p.right
        return result
### 二叉树前序、中后序遍历非递归实现 对于二叉树前序、中以及后序遍历,其主要区别在于访问节点相对于处理左右子树的位置不同。为了实现这些遍历方式的非递归版本,通常会采用栈来模拟递归调用的行为。 #### 前序遍历 (Pre-order Traversal)前序遍历中,首先访问根节点,接着依次访问左子树和右子树。下面是一个基于栈的数据结构用于存储待处理节点的方法: ```java public void preOrderTraversal(TreeNode root) { Stack<TreeNode> stack = new Stack<>(); while (!stack.isEmpty() || root != null) { if (root != null) { System.out.print(root.val + " "); // 访问当节点 stack.push(root); root = root.left; // 移动到左侧孩子 } else { TreeNode node = stack.pop(); root = node.right; // 转向右侧孩子继续探索 } } } ``` 此代码片段展示了如何通过显式管理一个外部栈来进行前序遍历[^1]。 #### 中遍历 (In-order Traversal) 当中遍历时,遵循的是先访问最左边的孩子直到叶子节点,再回溯并打印父节点最后才去右边分支的原则。这里同样可以利用栈帮助完成这一过程: ```c void inorderNonRecursive(struct Node* root){ struct Node *nodeStack[MAX]; int top=-1; struct Node *current=root; while(current!=NULL||top!=-1){ /* Reach the left most Node of the current Node */ while (current != NULL){ push(nodeStack, &top, current); // Push to stack until it reaches end. current=current->left; } /* Current must be NULL at this point */ if(top!=-1){ current=pop(nodeStack,&top); // Backtrack from empty subtree and visit parent node. printf("%d ",current->data); /* We have visited the node and its left subtree. Now, it's right subtree's turn */ current=current->right; } } } ``` 上述实现了使用C语言编写的中遍历逻辑[^2]. #### 后序遍历 (Post-order Traversal) 相较于其他两种顺来说,后序遍历更为复杂一些因为它需要确保每次返回上层时都能正确判断是否应该输出该层上的元素还是进一步深入下一层。一种常见的做法是在第二次遇到某个顶点时才真正对其进行操作: ```cpp struct TreeLinkNode{ int val; TreeLinkNode *left,*right; }; vector<int> postorderTraversal(TreeLinkNode *root) { vector<int> res; if(!root)return res; unordered_map<TreeLinkNode*,int> m; stack<TreeLinkNode*> s({root}); while(!s.empty()){ auto t=s.top();s.pop(); if(t->left&&m[t]!=2){ s.push(t); s.push(t->left); continue; } if(t->right&&!t->right->val==INT_MIN){ s.push(t); s.push(t->right); m[t]=2; continue; } res.push_back(t->val); t->val=INT_MIN;// mark as visited } return res; } ``` 这段伪码提供了一种解决策略,在实际应用中可能还需要调整以适应特定编程环境的要求[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值