欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

二叉树的遍历算法(一)

程序员文章站 2022-10-03 17:30:51
///*// 复习一下 树的遍历算法// 递归方法:前中后// 非递归方法:前中后+层次//// 树的定义://public class TreeNode {// int val;// TreeNode left;// TreeNode right;// TreeNode(int x){// val =x;// }//}////*///public class Q1 {//递归函数写的时候就跟手算是一样的...

二叉树的遍历算法

复习一下 树的遍历算法
递归方法:前中后
非递归方法:前中后+层次

树的定义:

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

    //递归函数写的时候就跟手算是一样的,只不过相应的读取变成一个存储或者输出的过程。
    //前序递归
    public static void RecurPreOrder(TreeNode root){
        if(root !=null){
            System.out.println(root.val);
            RecurPreOrder(root.left);
            RecurPreOrder(root.right);
        }
    }
    //中序递归
    public static void RecurInOrder(TreeNode root){
        if(root != null){
            RecurInOrder(root.left);
            System.out.println(root.val);
            RecurInOrder(root.right);
        }
    }
    //后序递归
    public static void RecurPostOrder(TreeNode root){
        if(root != null){
            RecurPostOrder(root.left);
            RecurPostOrder(root.right);
            System.out.println(root.val);

        }
    }



    //先序遍历的非递归算法使用的是栈,迭代核心的是“栈顶是根节点,访问,遍历先右后左,”
    //前序非递归
    public static List<Integer> NonRecurPreOrder(TreeNode root){
        List<Integer> list = new ArrayList<Integer>();
        if (root == null) return list;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        while( !stack.empty()){
            TreeNode p = stack.pop();
            list.add(Integer.valueOf(p.val));

            if(p.right != null){
                stack.push(p.right);
            }
            if(p.left  != null){
                stack.push(p.left);
            }
        }
        return list;

    }


    //中序遍历的非递归算法
    //还是利用栈:迭代的思想是,栈顶是左节点,访问发生在该节点无左子树的时候
    public static List<Integer> NonRecurInOrder(TreeNode root){
        List<Integer> list = new ArrayList<Integer>();
        if(root ==null) return list;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode tmp = root;
        while (! stack.empty()|| tmp != null){
            //1.遍历全部左子树
            if(tmp!= null){
                stack.push(tmp);
                tmp = tmp.left;
            }else{
             //2.左子树遍历完成以后,栈顶元素依次出栈访问,如果栈顶元素存在右子树,右子树入栈迭代成为新的栈顶
                tmp = stack.pop();
                list.add(Integer.valueOf(tmp.val));
                tmp  = tmp.right;
                //这三步实现了不用额外的判断即可完成对于右子树的回溯NB
            }
        }
        return list;
    }

    //后序遍历的非递归算法:这个版本太奇淫技巧了,学不来学不来
    //依旧是利用栈:参考中序遍历的左-根-右,后序遍历的是 左-右-根
    public static List<Integer> NonRecurPostOrder(TreeNode root){
        LinkedList<Integer> list = new LinkedList<>();
        if(root ==null ) return list;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode tmp = root;
        while ( ! stack.empty() || tmp != null){
            //1. 遍历全部右子树,结果容器用队列表示,
            if(tmp !=null){
                list.addFirst(tmp.val);
                stack.push(tmp);
                tmp = tmp.right;
            }else{
                //2.右子树遍历完成以后,栈顶元素依次出栈,如果存在的左子树,返回1。
                tmp = stack.pop();
                tmp = tmp.left;
            }
        }
        return list;
    }

    //参考另一个大佬的思路:
    //所谓的非递归算法就是使用栈来模仿递归,由栈的顺序可以知道,先入后出,所以:
    //前序遍历就是在访问访问左子树之前,对父节点进行访问。即左节点的出栈的时候
    //中序遍历就是在访问左子树之后,右子树之前,对父节点进行操作。
    //后序遍历就是在访问左右子树以后,对父节点进行操作。即左右子树都出栈以后

    public static List<Integer> NonRecurPreOrder2(TreeNode root) {
        if(root == null ) return Collections.emptyList();

        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();

        stack.push(root);

        while (! stack.empty()){
            //弹出节点用以判断节点是否已经访问,非空表示没有访问
            TreeNode t = stack.pop();

            if(t != null){
                if(t.right != null) stack.push(t.right);
                if(t.left != null) stack.push(t.left);
                stack.push(t);
                stack.push(null);
            }else{
                res.add(Integer.valueOf(stack.pop().val));
            }

        }
        return  res;


    }

    public static void main(String[] args) {
        String str = "[1,2,3,4,5,6]";
        TreeNode root = wrapper.stringToTreeNode(str);
        wrapper.prettyPrintTree(root);
        System.out.println(NonRecurPreOrder2(root));


    }


}

本文地址:https://blog.csdn.net/qq_33816775/article/details/107362140