ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

二叉树的按层打印与ZigZag打印

2022-01-26 12:34:01  阅读:157  来源: 互联网

标签:head null 打印 nLast right 二叉树 按层 节点 dq


二叉树的按层打印与ZigZag打印

题目:二叉树的按层打印与ZigZag打印

《程序员代码面试指南》第39题 P132 难度:尉★★☆☆

按层打印原本是非常基础的内容,对二叉树做简单的宽度优先遍历即可。不过本题有额外的要求,即同一层的节点必须打印在同一行上,并且要求输出行号

本题使用了2个Node类型的变量lastnLast。分别表示当前行的最右节点下一行的最右节点

如果发现遍历到的节点正好等于last,则说明应该换行。换行后,令last=nLast

对于nLast更新,只要让它一直跟踪最新加入队列的节点即可。易知,最新加入的节点一定是下一行的最右节点

public void printByLevel(Node head) {
    if (head == null) {
        return;
    }
    Queue<Node> queue = new LinkedList<Node>();
    int level = 1;
    Node last = head;
    Node nLast = null;
    queue.offer(head);
    System.out.print("Level " + (level++) + " : ");
    while (!queue.isEmpty()) {
        head = queue.poll();
        System.out.print(head.value + " ");
        if (head.left != null) {
            queue.offer(head.left);
            nLast = head.left;
        }
        if (head.right != null) {
            queue.offer(head.right);
            nLast = head.right;
        }
        if (head == last && !queue.isEmpty()) {
            System.out.print("\nLevel " + (level++) + " : ");
            last = nLast;
        }
    }
    System.out.println();
}

对于ZigZag打印,最终的结果也只是偶数行倒序输出而已,不过实现起来需要一个双端队列

这里需要额外说明一下,不能使用2个ArrayList或是2个Stack来实现,底层都是动态数组,当元素数量达到一定规模时将发生扩容,扩容的时间复杂度为O(N)。用该数据结构来实现,不够“纯粹”和“干净”。Stack最好平时也尽量减少使用,详见:为什么JDK建议使用ArrayDeque实现栈

使用双端队列实现ZigZag打印时,需要注意:

  1. 如果是从左到右的过程,那么一律从dq的头部弹出节点。如果当前节点有孩子节点,则让孩子节点以先左后右的顺序从尾部加入dq;
  2. 如果是从右到左的过程,那么一律从dq的尾部弹出节点。如果当前节点有孩子节点,则让孩子节点以先右后左的顺序从头部加入dq。

当遍历到的节点刚好等于last,则进行上面2种打印的切换

不过如何确定下一层的最后节点呢?不难发现,下一层最后打印的节点就是当前层有孩子节点的节点中最先加入dq的节点

public void printByZigZag(Node head) {
    if (head == null) {
        return;
    }
    Deque<Node> dq = new LinkedList<Node>();
    int level = 1;
    boolean lr = true;
    Node last = head;
    Node nLast = null;
    dq.offerFirst(head);
    pringLevelAndOrientation(level++, lr);
    while (!dq.isEmpty()) {
        if (lr) {
            head = dq.pollFirst();
            if (head.left != null) {
                nLast = nLast == null ? head.left : nLast;
                dq.offerLast(head.left);
            }
            if (head.right != null) {
                nLast = nLast == null ? head.right : nLast;
                dq.offerLast(head.right);
            }
        } else {
            head = dq.pollLast();
            if (head.right != null) {
                nLast = nLast == null ? head.right : nLast;
                dq.offerFirst(head.right);
            }
            if (head.left != null) {
                nLast = nLast == null ? head.left : nLast;
                dq.offerFirst(head.left);
            }
        }
        System.out.print(head.value + " ");
        if (head == last && !dq.isEmpty()) {
            lr = !lr;
            last = nLast;
            nLast = null;
            System.out.println();
            pringLevelAndOrientation(level++, lr);
        }
    }
    System.out.println();
}

public void pringLevelAndOrientation(int level, boolean lr) {
    System.out.print("Level " + level + " from ");
    System.out.print(lr ? "left to right: " : "right to left: ");
}

标签:head,null,打印,nLast,right,二叉树,按层,节点,dq
来源: https://www.cnblogs.com/CWZhou/p/15846087.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有