二叉树的遍历(Java)

       二叉树是一种常用的数据结构,常用的遍历方法有先序遍历,中序遍历,后序遍历和层次遍历。

定义二叉树节点

public class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int val){
        this.val=val;
    }
    public static void create(TreeNode root){
        TreeNode a = new TreeNode(2);
        TreeNode b = new TreeNode(3);
        TreeNode c = new TreeNode(4);
        TreeNode d = new TreeNode(5);
        TreeNode e = new TreeNode(6);
        TreeNode f = new TreeNode(7);
        TreeNode g = new TreeNode(8);
        TreeNode h = new TreeNode(9);
        TreeNode i = new TreeNode(10);
        root.left=a;root.right=b;
        a.left=c;   a.right=d;
        b.left=e;   b.right=f;
        d.left=g;   e.right=h;
        h.left=i;
    }
}
/**
 * 建造如下二叉树,用于测试
 *          1
 *         / \
 *        2   3
 *       /\   / \
 *      4  5  6  7
 *        /    \
 *       8      9
 *             /
 *            10
 *
 */

一、先序遍历

基本思想:先访问根节点,再访问左子树,再访问右子树;根节点——>左子树——>右子树

  • 递归
    public static void preOrder(TreeNode root){
        if(root!=null){
            System.out.print(root.val+" ");
            preOrder(root.left);
            preOrder(root.right);
        }
    }//1 2 4 5 8 3 6 9 10 7
  • 非递归

非递归用循环和栈实现,先遍历根节点,然后往左子树循环并入栈,遇到空即左子树遍历完了,出栈返回父节点,往右子树遍历

    public static void preOrder1(TreeNode root){
        LinkedList<TreeNode> stack = new LinkedList<>();
        TreeNode node = root;
        while(!stack.isEmpty()||node!=null){
            if(node!=null){
                System.out.print(node.val+" ");
                stack.push(node);
                node=node.left;
            }else{
                TreeNode node2 = stack.pop();
                node = node2.right;
            }
        }
    }//1 2 4 5 8 3 6 9 10 7 

二、中序遍历

基本思想:先访问左子树,再访问根节点,再访问右子树;左子树——>根节点——>右子树

  • 递归
    public static void inOrder(TreeNode root){
        if(root!=null){
            inOrder(root.left);
            System.out.print(root.val+" ");
            inOrder(root.right);
        }
    }//4 2 8 5 1 6 10 9 3 7

  • 非递归

跟先序遍历有点不同,这次要遍历到最左端(最靠左的节点)才开始输出

    public static void inOrder1(TreeNode root){
        LinkedList<TreeNode> stack = new LinkedList();
        TreeNode node = root;
        while(node!=null||!stack.isEmpty()){
            if(node!=null){
                stack.push(node);
                node=node.left;
            }else{
                TreeNode node2 = stack.pop();
                System.out.print(node2.val+" ");
                node = node2.right;
            }
        }
    }//4 2 8 5 1 6 10 9 3 7 

三、后序遍历

基本思想:先访问左子树,再访问右子树,再访问根节点;左子树——>右子树——>根节点

  • 递归
    public static void postOrder(TreeNode root){
        if(root!=null){
            postOrder(root.left);
            postOrder(root.right);
            System.out.print(root.val+" ");
        }
    }//4 8 5 2 10 9 6 7 3 1
  • 非递归

后序遍历也是先要往左遍历,当遇到空时,返回父节点即出栈,若此节点右子树不为空则要先往右子树遍历,此时把此节点用数组保存起来,表示该节点的右子树已经访问过了,避免从右子树返回父节点时发现此节点有右子树而又往已经遍历的右子树遍历,造成死循环,这样数组保存起来的节点再次遇到就可以直接输出了。

public static void postOrder1(TreeNode root){
        LinkedList<TreeNode> stack = new LinkedList<>();
        List<TreeNode> vis = new ArrayList<>();
        TreeNode node = root;
        while(!stack.isEmpty()||node!=null){
            if(node!=null){
                stack.push(node);
                node=node.left;
            }else{
                TreeNode node2 = stack.pop();
                if(node2.right!=null){
                    if(!vis.contains(node2)){
                        stack.push(node2);
                        node = node2.right;
                        vis.add(node2);
                    }else {
                        System.out.print(node2.val + " ");
                    }
                }else{
                    System.out.print(node2.val+" ");
                    node = node2.right;
                }
            }
        }
    }//4 8 5 2 10 9 6 7 3 1 

四、层次遍历

这是leetcode上的题目 :二叉树的层次遍历

输出层次遍历并按层次输出。

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        if(root==null) return new ArrayList<>();
        LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        List<List<Integer> > list = new ArrayList<List<Integer> >();
        while(!queue.isEmpty()){
            int cnt = queue.size();
            ArrayList<Integer> temp = new ArrayList<>();
            while(cnt>0){
                TreeNode node = queue.poll();
                temp.add(node.val);
                if(node.left!=null)
                    queue.offer(node.left);
                if(node.right!=null)
                    queue.offer(node.right);
                cnt--;
            }
            list.add(temp);
        }
        return list;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值