二叉树遍历(先序、中序、后序)栈

递归的方法以及二叉树的构建代码在前文
https://blog.csdn.net/qq_36879870/article/details/90517407
先把例子拿一下过来
在这里插入图片描述

前序遍历

输出为根左右,输出完根后要保留,因为先说出左,后输出右,当右还没有处理的时候放到栈中存储。
由此可以推断出一些规律

  1. 输出当前节点的值
  2. 循环获取左子树
  3. 放入栈中
  4. 当左子为null时开始处理右子
  5. 当左子处理完了之后开始处理栈中的数据
  6. 循环取出栈顶的数据直至栈空
// 前序遍历--栈
public static void preorderTraversalByStack(TreeNode root){
    Stack<TreeNode> treeNodeStack = new Stack<>();
    // 指定游标为当前root
    TreeNode node = root;
    // 游标不为空(无子节点)或者栈内还有元素则一直循环
    while(node!=null || !treeNodeStack.empty()){
        // 当前游标不为空,循环处理左侧节点
        while (node!=null){
            // 前序遍历输出当前节点值
            System.out.print(node.getValue());
            // 将当前节点存入栈内以便后续处理右侧节点
            treeNodeStack.push(node);
            // 将游标指向左节点
            node = node.getLeft();
        }
        // 开始处理右侧节点
        if(!treeNodeStack.empty()){
            // 将当前节点弹出栈
            node = treeNodeStack.pop();
            // 将游标指向右节点
            node = node.getRight();
        }
    }
}
中序遍历

中序遍历输出结果为左根右,与前序遍历类似,只是执行输出的时间不一致
因为需要先找到最左的才输出
因此在那边切换为右子的时候输出就好了

  1. 循环获取左子树
  2. 放入栈中
  3. 当左子树为null时
  4. 输出当前节点的值
  5. 开始处理右子树
  6. 循环取出栈顶的数据直至栈空
//中序遍历--栈
public static void inorderTraversalByStack(TreeNode root){
    Stack<TreeNode> treeNodeStack = new Stack<>();
    // 指定游标为当前root
    TreeNode node = root;
    // 游标不为空(无子节点)或者栈内还有元素则一直循环
    while(node!=null || !treeNodeStack.empty()){
        while (node!=null){
            treeNodeStack.push(node);
            node = node.getLeft();
        }
        if(!treeNodeStack.empty()){
            node = treeNodeStack.pop();
            System.out.print(node.getValue());
            node = node.getRight();
        }
    }
}
后序遍历

输出顺序为左右根,这与前中序遍历有个明显的差别,需要左右子都处理完了才能处理根,因此处理根前要判断左右子是否已经处理完了
因此节点的输出条件为
左右子节点:左右子均为null
根节点:左右均已处理
因为又是先处理左边的,所以只需要考虑右边是否已经处理,若已经处理则处理根节点
引入一个新的游标lastvisited每次指向已处理的节点

  1. 循环获取左子放入栈中
  2. 当左子为null时查看栈顶元素的右子
  3. 若右子也为null则输出栈顶元素并将lastvisited指向该元素,否则继续循环处理该元素右子
  4. 若栈顶元素的右子==lastvisited(意味着左右子都已经处理了)则输出该元素,否则游标指向该元素右子继续处理
//后序遍历--栈
public static void postorderTraversalByStack(TreeNode root) {
    Stack<TreeNode> treeNodeStack = new Stack<>();
    // 指定游标为当前root
    TreeNode node = root;
    TreeNode lastVisted = root;
    // 游标不为空(无子节点)或者栈内还有元素则一直循环
    while (node != null || !treeNodeStack.empty()) {
        while (node != null) {
            treeNodeStack.push(node);
            node = node.getLeft();
        }
        node = treeNodeStack.peek();
        if (node.getRight() == null || node.getRight() == lastVisted) {
            node = treeNodeStack.pop();
            System.out.print(node.getValue());
            lastVisted = node;
            node = null;
        } else {
            node = node.getRight();
        }
    }
}

上传不了手稿图。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值