非递归实现前序遍历、中序遍历、后序遍历(用栈和 List)

ps: 非递归 写 递归 要用 栈,用 List 也可实现。

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class ListTree {
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) { val = x; }
    }

    public void preorderTraversal(TreeNode root) {
        //给定一个二叉树,返回它的 前序 遍历(非递归)
        
        //1.创建一个栈。初始情况下,把根节点入栈
        //2.进入循环
        // a.取栈顶元素(出栈)
        // b.访问该元素
        // c.若该元素的右子树不为空,就入栈;
        //   若该元素的左子树不为空,也入栈;
        //   当栈为空时,遍历完成

        if(root == null) {
            return;
        }
        Stack<TreeNode> stack = new Stack<>();//创建一个栈
        stack.push(root);//根节点
        while(!stack.isEmpty()) {
            TreeNode top = stack.pop();//取出栈顶元素
            System.out.print(top.val + " ");//输出栈顶元素
            if(top.right != null) {
                stack.push(top.right);
            }
            if(top.left != null) {
                stack.push(top.left);
            }
        }
    }
    //用 List 写非递归的先序遍历
    public List<Integer> preorderTraversal1(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null) {
            return list;
        }
        Stack<TreeNode> stack = new Stack<>();//创建一个栈
        stack.push(root);//根节点
        while(!stack.isEmpty()) {
            TreeNode top = stack.pop();//取出栈顶元素
            //System.out.print(top.val + " ");//输出栈顶元素
            list.add(Integer.valueOf(top.val));
            if(top.right != null) {
                stack.push(top.right);
            }
            if(top.left != null) {
                stack.push(top.left);
            }
        }
        return list;
    }

    public void inorderTraversal(TreeNode root) {
        //给定一个二叉树,返回它的 中序 遍历(非递归)
        //1.创建一个栈
        //2.设定一个 cur 引用从 root 出发
        //  只要 cur 不为空,就把 cur 入栈 同时 cur 往左移动
        //  cur 为空(此时的栈顶元素就是当前的最左侧元素),出栈并访问栈顶元素
        //3.让 cur 指向刚才被访问的节点的右子树,循环执行 1 2 步骤

        if(root == null) {
            return;
        }
        Stack<TreeNode> stack = new Stack<>();//创建一个栈
        TreeNode cur = root;
        while(true) {
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            if(stack.empty()) {
                break;
            }
            TreeNode top = stack.pop();//取出栈顶元素
            System.out.print(top.val + " ");//输出栈顶元素
            cur = top.right;
        }
    }
    public List<Integer> inorderTraversal1(TreeNode root) {
        //用 List 写非递归的中序遍历
        List<Integer> list = new ArrayList<>();
        if(root == null) {
            return list;
        }
        Stack<TreeNode> stack = new Stack<>();//创建一个栈
        TreeNode cur = root;
        while(true) {
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            if(stack.empty()) {
                break;
            }
            TreeNode top = stack.pop();//取出栈顶元素
            list.add(top.val);
            cur = top.right;
        }
        return list;
    }

    public void postorderTraversal(TreeNode root) {
        //给定一个二叉树,返回它的 后序 遍历(非递归)
        //1. 创建一个栈
        //2. 创建 cur 从 root 出发
        //   只要 cur 不为空,就把 cur 入栈 同时 cur 往左移动
        //   cur 为空,取栈顶元素,判断能不能访问
        //     a.栈顶元素右子树为 null 时可以访问
        //     b.栈顶元素右子树已被访问过 可以访问(创建 prev 变量判断)
        //栈顶元素可被访问,出栈; 否则还得在栈里
        //3.若栈顶元素不满足访问条件,则让 cur 从栈顶元素右子树出发,继续进行 1 2

        if (root == null) {
            return;
        }
        Stack<TreeNode> stack = new Stack<>();//创建一个栈
        TreeNode cur = root;
        TreeNode prev = null;//初始情况下没有任何节点被访问过
        while (true) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            if (stack.empty()) {
                break;
            }
            TreeNode top = stack.peek();//取出栈顶元素, 开始判断
            if(top.right == null || top.right == prev) {
                System.out.print(top.val + " ");
                stack.pop();
                prev = top;
            }else {
                cur = top.right;
            }
        }
    }
    public List<Integer> postorderTraversal1(TreeNode root) {
        // 用 List 写非递归的 后序 遍历
        List<Integer> list = new ArrayList<>();
        if (root == null) {
            return list;
        }
        Stack<TreeNode> stack = new Stack<>();//创建一个栈
        TreeNode cur = root;
        TreeNode prev = null;//初始情况下没有任何节点被访问过
        while (true) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            if (stack.empty()) {
                break;
            }
            TreeNode top = stack.peek();//取出栈顶元素, 开始判断
            if(top.right == null || top.right == prev) {
                list.add(top.val);
                stack.pop();
                prev = top;
            }else {
                cur = top.right;
            }
        }
        return list;
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
通过前序遍历中序遍历后序遍历的方法如下: 1. 首先,我们知道前序遍历的特点是先访问根节点,然后遍历左子树,最后遍历右子树。而中序遍历的特点是先遍历左子树,然后访问根节点,最后遍历右子树。 2. 根据这两种遍历的特点,我们可以确定根节点的位置。在前序遍历中,第一个节点就是根节点;而在中序遍历中,根节点的位置是在左子树的节点之后。 3. 接下来,我们可以将前序遍历中序遍历分为左子树和右子树两部分。左子树的节点在前序遍历中序遍历中都是连续的,右子树的节点在前序遍历中序遍历中也是连续的。 4. 根据左子树和右子树的节点数目,我们可以将前序遍历中序遍历进一步分割成更小的部分。对于左子树,我们可以再次使用前序遍历中序遍历求解后序遍历;同样地,对于右子树也是如此。 5. 重复上述步骤,直到只剩下一个节点。此时,我们就得到了整颗二叉树后序遍历序列。 所以通过前序遍历中序遍历可以求得后序遍历。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [二叉树前序中序后序遍历相互求法](https://blog.csdn.net/liuchen1206/article/details/8542996)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [已知先序遍历序列和中序遍历序列,求后序遍历序列](https://blog.csdn.net/qq_40685275/article/details/100177830)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值