Layer by layer printing and ZigZag printing of binary tree
Title: Layer by layer printing and ZigZag printing of binary tree
"Programmer code interview guide" question 39 P132 difficulty: Wei ★★☆
Printing by layer is originally a very basic content. You can simply traverse the width of the binary tree first. However, there are additional requirements in this topic, that is, the nodes of the same layer must be printed on the same line, and the line number is required to be output.
This question uses two Node type variables, last and nLast. Represents the rightmost Node of the current row and the rightmost Node of the next row respectively.
If it is found that the traversed node is exactly equal to last, it indicates that it should wrap. After line feed, make last=nLast.
For the update of nLast, just let it keep track of the newly queued nodes. It is easy to know that the newly added node must be the rightmost node in the next row.
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(); }
For ZigZag printing, the final result is only the reverse order output of even rows, but it needs a double ended queue to implement.
It should be noted that two ArrayList s or two stacks cannot be used. The bottom layer is a dynamic array. When the number of elements reaches a certain scale, capacity expansion will occur, and the time complexity of capacity expansion is O(N). It is not "pure" and "clean" enough to implement with this data structure. Stack should also be used as little as possible at ordinary times. See the following for details: Why does JDK recommend using ArrayDeque implementation stack
When using double ended queue to realize ZigZag printing, you should pay attention to:
- If the process is from left to right, all nodes will pop up from the head of dq. If the current node has child nodes, let the child nodes join dq from the tail in the order of left to right;
- If the process is from right to left, all nodes will pop up from the tail of dq. If the current node has child nodes, let the child nodes join dq from the head in the order of right to left.
When the traversed node is just equal to last, switch between the above two types of printing.
But how to determine the last node of the next layer? It is not difficult to find that the last printed node of the next layer is the first node to join dq among the nodes with child nodes in the current layer.
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: "); }