树的遍历——深度优先遍历、广度优先遍历

遍历

  • 遍历可以分为深度优先遍历、广度优先遍历.深度优先遍历用递归方案比较简单,广度优先遍历似乎没有很合适的递归方案,采用非递归实现简单
  • 遍历有对二叉树的遍历和对多叉树的遍历
  • 二叉树遍历分为先根遍历、中根遍历、后根遍历

遍历的思想

  • 树是怎样的一个结构呢?每个节点都包含着它的子节点的信息,所以可以通过本节点发现它的下一个节点
  • 遍历树可以分为两个操作:
    • 一、遍历每一个节点
    • 二、处理节点的操作,下面程序里就是handleNode方法.
  • 处理节点操作在程序中的前后位置影响了是先根、中根、后根遍历

多叉树

多叉树

  • 节点类
/**
 * 一个简单的多叉树节点类(静态内部类)
 */
static class TreeNode {

    public int value = 0;
    public List<TreeNode> nodeList = new ArrayList();// represent child node

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

  • 首先创建一个树
/**创建树*/
    public static TreeNode initTree() {
        TreeNode root = new TreeNode(0);
        TreeNode one = new TreeNode(1);
        TreeNode two = new TreeNode(2);
        TreeNode three = new TreeNode(3);
        TreeNode four = new TreeNode(4);
        TreeNode five = new TreeNode(5);
        TreeNode six = new TreeNode(6);
        TreeNode seven = new TreeNode(7);
        TreeNode eight = new TreeNode(8);
        TreeNode nine = new TreeNode(9);
        TreeNode ten = new TreeNode(10);

        root.nodeList.add(one);
        root.nodeList.add(two);
        root.nodeList.add(three);
        one.nodeList.add(four);
        one.nodeList.add(five);
        two.nodeList.add(six);
        two.nodeList.add(seven);
        two.nodeList.add(eight);
        three.nodeList.add(nine);
        three.nodeList.add(ten);
        return root;
    }
  • 主函数
   public static void main(String[] args) {
       TreeNode root = initTree();
       traversal_1(root);
   }
  • 遍历
   /**先根遍历、递归遍历、深度优先遍历*/
   public static void traversal(TreeNode root){
       handleNode(root);
       for(TreeNode node : root.nodeList){
           traversal(node);
       }
   }
   /**处理类*/
   public static void handleNode(TreeNode node){
       System.out.print(node.value + " ");
   }

输出的结果

0 1 4 5 2 6 7 8 3 9 10 
  • 如果改变handleNode方法的位置,会变为后根遍历
    /**后根遍历、递归遍历、深度优先遍历*/
    public static void traversal(TreeNode root) {
        for (TreeNode node : root.nodeList) {
            traversal(node);
        }
        handleNode(root);
    }

输出结果

4 5 1 6 7 8 2 9 10 3 0 

二叉树

二叉树

  • 节点类
    /**一个简单的二叉树类*/
    static class TreeNode {
        public int value = 0;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(int value, @Nullable TreeNode left, @Nullable TreeNode right) {
            this.value = value;
            this.left = left;
            this.right = right;
        }
        public TreeNode(int value) {
            this(value, null, null);
        }
    }
  • 创建树
   /**创建树*/
    public static TreeNode initTree() {
        TreeNode root = new TreeNode(0);
        TreeNode one = new TreeNode(1);
        TreeNode two = new TreeNode(2);
        TreeNode three = new TreeNode(3);
        TreeNode four = new TreeNode(4);
        TreeNode five = new TreeNode(5);
        TreeNode six = new TreeNode(6);
        TreeNode seven = new TreeNode(7);
        TreeNode eight = new TreeNode(8);
        TreeNode nine = new TreeNode(9);
        TreeNode ten = new TreeNode(10);

        root.left = one;
        root.right = two;
        one.left = three;
        one.right = four;
        two.left = five;
        two.right = six;
        three.left = seven;
        three.right = eight;
        four.left = nine;
        four.right = ten;

        return root;
    }
  • 遍历
   /**先根遍历、递归遍历、深度优先遍历*/
    public static void traversal(TreeNode root) {
        handleNode(root);
        if(root.left != null){
            traversal(root.left);
        }
        if (root.right != null){
            traversal(root.right);
        }
    }

主函数不变, 输出结果:

0 1 3 7 8 4 9 10 2 5 6
  • 中根遍历、后根遍历
   /**中根遍历、递归遍历、深度优先遍历*/
    public static void traversal(TreeNode root) {
        if(root.left != null){
            traversal(root.left);
        }
        handleNode(root)
        if (root.right != null){
            traversal(root.right);
        }
    }
    /**后根遍历、递归遍历、深度优先遍历*/
    public static void traversal(TreeNode root) {
        if(root.left != null){
            traversal(root.left);
        }
        if (root.right != null){
            traversal(root.right);
        }
        handleNode(root)
    }

深度优先遍历、先根遍历、栈实现.

  • 中根遍历和后根遍历需要引入一些条件判断来实现.
    /**
     * 非递归遍历、深度优先遍历、先根遍历,用栈实现
     * 先根、中跟、后根和根节点入栈的顺序有关
     */
    public static void traversal(TreeNode root) {
        if (root == null) return;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        TreeNode node;
        while (!stack.isEmpty()) {
            node = stack.pop();
            handleNode(node);
            if (node.right != null) stack.push(node.right);
            if (node.left != null) stack.push(node.left);
        }
    }

输出结果:

0 1 3 7 8 4 9 10 2 5 6 

广度优先遍历、队列实现、非递归遍历

  • 当遍历到一个节点的时候,对节点进行操作(handleNode)之后,还有把这个节点的下一层子节点放进队列.
    /**非递归遍历、广度优先遍历、队列实现*/
    public static void traversal(TreeNode root) {
        if (root == null) return;
        Queue<TreeNode> queue = new ArrayDeque<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            handleNode(node);
            if (node.left != null) {
                queue.offer(node.left);
            }
            if (node.right != null) {
                queue.offer(node.right);
            }
        }
    }
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值