二叉树的遍历

实现二叉树先序,中序和后序遍历

http://www.nowcoder.com/questionTerminal/a9fec6c46a684ad5a3abd4e365a9d362

题目链接:
二叉树遍历主要有两种,递归和非递归的遍历,第一种递归式的,比较简单,下面是我代码的模拟:

package AAAA;
import java.util.ArrayList;

/***
 * https://www.nowcoder.com/practice/a9fec6c46a684ad5a3abd4e365a9d362?tpId=188&tags=&title=&diffculty=0&judgeStatus=0&rp=1
 * 二叉树的先序后序中序遍历
 */
public class demo171 {

    public static class TreeNode {
        int var = 0;
        TreeNode left = null;
        TreeNode right = null;

        public TreeNode(int var) {
            this.var = var;
        }
    }

    public static void main(String[] args) {
        //threeOrders(0)
        //建立一个二叉树
        TreeNode root= new TreeNode(1);
        TreeNode leftNode= new TreeNode(2);
        TreeNode rightNode= new TreeNode(3);
        TreeNode leftNode1= new TreeNode(4);
        root.left=leftNode;
        root.right=rightNode;
        leftNode.left=leftNode1;
        //遍历出二叉树
        int[][] result = threeOrders(root);
        System.out.println("先序遍历为:"+first);
        System.out.println("中序遍历为:"+mid);
        System.out.println("后序遍历为:"+last);
        for (int[] ints : result) {
            for (int i = 0; i < ints.length; i++) {
                System.out.print(ints[i]+" ");
            }
            System.out.println("");
        }
    }


    private static ArrayList<Integer> first=new ArrayList<>();
    private static ArrayList<Integer> mid=new ArrayList<>();
    private static ArrayList<Integer> last=new ArrayList<>();

    public static int[][] threeOrders (TreeNode root) {
       int[][] result=new int[3][];
       firstCode(root);
       midCode(root);
       lastCode(root);
       result[0]=toIntArray(first);
       result[1]=toIntArray(mid);
       result[2]=toIntArray(last);
       return result;
    }
//先序
    private static void firstCode(TreeNode root) {
        if (root != null) {
            first.add(root.var);
            firstCode(root.left);
            firstCode(root.right);
        }
    }
//中序
    private static void midCode(TreeNode root) {
        if (root != null) {
            midCode(root.left);
            mid.add(root.var);
            midCode(root.right);
        }
    }
//后续遍历
    private static void lastCode(TreeNode root) {
        if (root != null) {
            lastCode(root.left);
            lastCode(root.right);
            last.add(root.var);
        }
    }

    //讲ArrayList转换为整型数组
    private static final int[] toIntArray(ArrayList<Integer> arrayList){
        int[] intArray = arrayList.stream().mapToInt(Integer::intValue).toArray();
        return intArray;
    }
}

由于递归比较耗时,下面这个是使用栈结构进行辅助的非递归解法,特别注意,为什么要是使用栈的结构,而不直接使用while循环,这里主要有两点:
1,使用栈结构可以对栈进行记录,是否为空,这是单纯的while循环用不到的
2,先进后出的特性
下面这个是我没有借助于栈结构写的代码,相信聪明的你已经发现其中的问题了,展示一下

package AAAA;

import java.util.ArrayList;
import java.util.LinkedList;

public class demo174 {
    //自定义树的数据结构
    public static class TreeNode {
        int var = 0;
        TreeNode left = null;
        TreeNode right = null;
        public TreeNode(int var) {
            this.var = var;
        }
    }

    public static void main(String[] args) {
        TreeNode root= new TreeNode(1);
        TreeNode leftNode= new TreeNode(2);
        TreeNode rightNode= new TreeNode(3);
        root.left=leftNode;
        root.right=rightNode;
        pp1(root);
        pp2(root);
        pp3(root);
        System.out.println(first);
        System.out.println(mid);
        System.out.println(last);

    }

    private static ArrayList<Integer> first=new ArrayList<>();
    private static ArrayList<Integer> mid=new ArrayList<>();
    private static ArrayList<Integer> last=new ArrayList<>();

    public static int[][] threeOrders (TreeNode root) {
        int[][] result=new int[3][];
        pp1(root);
        pp2(root);
        pp3(root);
        result[0]=toIntArray(first);
        result[1]=toIntArray(mid);
        result[2]=toIntArray(last);
        return result;
    }


    private static void pp1(TreeNode root){
        if(root!=null){
            first.add(root.var);
            TreeNode p=root;
            while(p.left!=null){
                p=p.left;
                first.add(p.var);
            }
            TreeNode q=root;
            while(q.right!=null){
                q=q.right;
                first.add(q.var);
            }
        }

    }
    private static void pp2(TreeNode root){
        if(root!=null){
            TreeNode p=root;
            while(p.left!=null){
                p=p.left;
                mid.add(p.var);
            }
            mid.add(root.var);
            TreeNode q=root;
            while(q.right!=null){
                q=q.right;
                mid.add(q.var);
            }
        }

    }
    private static void pp3(TreeNode root){
        if(root!=null){
            TreeNode p=root;
            while(p.left!=null){
                p=p.left;
                last.add(p.var);
            }
            TreeNode q=root;
            while(q.right!=null){
                q=q.right;
                last.add(q.var);
            }
        }
        last.add(root.var);
    }

    private static void pp4(TreeNode root){
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while(!queue.isEmpty()){
            root = queue.pop();
            System.out.print(root.var+" ");
            if(root.left!=null) {
                queue.add(root.left);
            }
            if(root.right!=null) {
                queue.add(root.right);
            }
        }
    }

    //讲ArrayList转换为整型数组
    private static final int[] toIntArray(ArrayList<Integer> arrayList){
        int[] intArray = arrayList.stream().mapToInt(Integer::intValue).toArray();
        return intArray;
    }
}

使用栈解决模拟递归遍历要注意一点,后序遍历需要设计标记值,所以说栈是完全可以替代递归的

package AAAA;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Stack;

public class demo173 {
    //自定义树的数据结构
    public static class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;
        public TreeNode(int val) {
            this.val = val;
        }
    }

    public static void main(String[] args) {
        TreeNode root= new TreeNode(1);
        TreeNode leftNode= new TreeNode(2);
        TreeNode rightNode= new TreeNode(3);
        root.left=leftNode;
        root.right=rightNode;
        pp1(root);
        pp2(root);
        pp3(root);
        System.out.println(first);
        System.out.println(mid);
        System.out.println(last);

    }

    private static ArrayList<Integer> first=new ArrayList<>();
    private static ArrayList<Integer> mid=new ArrayList<>();
    private static ArrayList<Integer> last=new ArrayList<>();

    public static int[][] threeOrders (TreeNode root) {
        int[][] result=new int[3][];
        pp1(root);
        pp2(root);
        pp3(root);
        result[0]=toIntArray(first);
        result[1]=toIntArray(mid);
        result[2]=toIntArray(last);
        return result;
    }


    private static void pp1(TreeNode root){
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode treeNode = root;
        while(treeNode!=null || !stack.isEmpty()){
            //迭代访问节点的左孩子,并入栈
            while(treeNode != null){
                first.add(treeNode.val);
                stack.push(treeNode);
                treeNode = treeNode.left;
            }
            //如果节点没有左孩子,则弹出栈顶节点,访问节点右孩子
            if(!stack.isEmpty()){
                treeNode = stack.pop();
                treeNode = treeNode.right;
            }
        }
    }
    private static void pp2(TreeNode root){
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode treeNode = root;
        while(treeNode!=null || !stack.isEmpty()){
            while(treeNode != null){
                stack.push(treeNode);
                treeNode = treeNode.left;
            }
            if(!stack.isEmpty()){
                treeNode = stack.pop();
                mid.add(treeNode.val);
                treeNode = treeNode.right;
            }
        }
    }
    private static void pp3(TreeNode root){
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode treeNode = root;
        TreeNode lastVisit = null;   //标记每次遍历最后一次访问的节点
        while(treeNode!=null || !stack.isEmpty()){//节点不为空,结点入栈,并且指向下一个左孩子
            while(treeNode!=null){
                stack.push(treeNode);
                treeNode = treeNode.left;
            }
            //栈不为空
            if(!stack.isEmpty()){
                //出栈
                treeNode = stack.pop();
                if(treeNode.right == null || treeNode.right == lastVisit) {
                    last.add(treeNode.val);
                    lastVisit = treeNode;
                    treeNode  = null;
                }else{
                    stack.push(treeNode);
                    treeNode = treeNode.right;
                }
            }
        }
    }

    private static void pp4(TreeNode root){
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while(!queue.isEmpty()){
            root = queue.pop();
            System.out.print(root.val+" ");
            if(root.left!=null) {
                queue.add(root.left);
            }
            if(root.right!=null) {
                queue.add(root.right);
            }
        }
    }

    //讲ArrayList转换为整型数组
    private static final int[] toIntArray(ArrayList<Integer> arrayList){
        int[] intArray = arrayList.stream().mapToInt(Integer::intValue).toArray();
        return intArray;
    }
}
全部评论

相关推荐

暮雨轻歌:看起来hr不能接受我菜查看图片
点赞 评论 收藏
分享
不放弃的小鱼干很洒脱:好可爱的离职理由
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务