按层遍历二叉树

准备工作

1.一个Node节点类

/**
 * @Deacription 二叉树节点
 * @Author BarryLee
 * @Date 2019/12/7 9:11
 */
public class Node {
  public int value;
  public Node left;
  public Node right;
  public Node(int value) {
    this.value = value;
  }
}

2.初始化一棵树用于测试(可以画一下看看,很简单,这里省略)

  Node head;
  @Before
  public void before() {
    // 先构建一棵树
    head = new Node(1);
    head.left = new Node(2);
    head.right = new Node(3);
    head.left.left = new Node(4);
    head.right.left = new Node(5);
    head.right.right = new Node(6);
    head.right.left.left = new Node(7);
    head.right.right.right = new Node(8);
  }
一、不打印当前层次

思路很简单,因为是按层来进行遍历,那肯定是使用队列(先进先出的原理)来实现了

1.先将头节点head放进队列

2.while循环遍历这个队列

3.poll拿出队列里的第一个节点cur

4.如果cur的左子节点不为空,放进队列

5.如果cur的右子节点不为空,放进队列

6.打印cur的值

  @Test
  public void test1() {
    Queue<Node> queue = new LinkedList<>();
    queue.add(head);
    while(queue.size()>0) {
      Node cur = queue.poll();
      if(cur.left != null) {
        queue.add(cur.left);
      }
      if(cur.right != null) {
        queue.add(cur.right);
      }
      System.out.println(cur.value);
    }
  }

输出结果:

1 2 3 4 5 6 7 8 

二、打印当前层次

基于上一个Demo,这个比不打印层次要复杂一点点,复杂在如何确定换行的时机,其实last和nlast两个变量就可以解决这个问题

解题思路

1.初始化变量,重点关注last和nlast

2.last表示当前行的最后一个节点,nlast表示下一行的最后一个节点

3.怎么确定last的值: 开始的时候为head没有问题,之后的每一行都是等于nlast

4.那么问题就变成了怎么确定nlast: 每次放入一个节点我们就把这个节点的子节点作为nlast(必须是从左往右)

再看一遍执行步骤

1.初始化参数,last==nlast==head。第一个节点进来队列,然后开始循环

2.弹出节点cur

3.如果左子节点不为空则进队列,并且nlast为cur的左子节点

4.如果右子节点不为空则进队列,并且nlast为cur的右子节点(所以现在的nlast就是head.right了)

5.打印cur:如果cur==last则换行,现在是头节点,所以换行

6.然后到了下一行,弹出head.left,重复步骤 3 & 4

7.注意,这时last是head.right,所以还没到换行的时机,经过上面的操作nlast变成了head.left.right,打印

8.然后继续遍历,弹出head.right,重复步骤 3 & 4

9.此时cur==last,该换行了,而nlast也变成了head.right.right

10.将nlast赋值给last,为什么呢,因为你要进下一行了呀,而下一行的最后一个节点就是nlast

11.如此反复,AC撒花


  /**
   * 按层遍历 -- 不打印当前是多少层
   */
  @Test
  public void test2() {
    Queue<Node> queue = new LinkedList<>();
    queue.add(head);
    // 节点所在层次
    int level = 0;
    // 是否为当前层的第一个
    boolean isFirst = true;
    // 当前打印所在行的最后一个节点
    Node last = head;
    // 下一行的最后一个节点
    Node nlast = head;

    // 遍历
    while(queue.size()>0) {
      Node cur = queue.poll();

      if(cur.left != null) {
        queue.add(cur.left);
        nlast = cur.left;
      }
      if(cur.right != null) {
        queue.add(cur.right);
        nlast = cur.right;
      }

      if(isFirst) {
        System.out.print("level" + ++level + "->");
      }
      // 当前节点是当前行最后一个节点 -- 换行
      if(last==cur) {
        last = nlast;
        isFirst = true;
        System.out.println(cur.value);
      } else {
        isFirst = false;
        System.out.print(cur.value + " ");
      }
    }
  }

输出结果:

level1->1
level2->2 3
level3->4 5 6
level4->7 8

每天进步一点点!


逸川同学
8 声望0 粉丝

| || o _| |) | ._ |_| _ |


引用和评论

0 条评论