一,問題描述
請構造一棵二叉樹,並按照“之字形”順序打印這棵二叉樹。
所謂“之字形”打印,第一行是從左到右打印,第二行是從右到左打印,第三行又是從左到右打印....
即,奇數行(根為第一行)是從左到右打印,而偶數行是從右到左打印。

如上圖:該二叉樹的打印順序為:
20
30 10
12 25
二,問題分析
①定義兩個棧一個名為 stack,另一個為nextStack,stack 只保存奇數行的結點,nextStack只保存偶數行的結點。並定義一個整形變量lineNumber 來標記行號,以判斷當前打印的行是奇數行結點還是偶數行結點。
②當打印stack中的結點時,將該結點的孩子按照先 左孩子、后 右孩子的順序 保存到nextStack棧中。
③當打印nextStack中的結點時,將該結點的孩子按照先 右孩子,后 左孩子的順序 保存到 stack棧中。
復雜度分析:
由於每個結點都會入棧一次,然后出棧打印。故時間復雜度為O(N)
代碼中使用了兩個輔助棧,分別用來保存奇數行的結點和偶數行的結點。故空間復雜度也是O(N)
三,完整代碼
import java.util.LinkedList; public class PrintZigzag { private class BinaryNode{ int ele; BinaryNode left; BinaryNode right; public BinaryNode(int ele) { this.ele = ele; left = right = null; } @Override public String toString() { return ele + " "; } } private BinaryNode root; //根據數組 arr 中的元素構造一棵二叉排序樹 public void buildTree(int[] arr){ for (int node : arr) { insert(node); } } private void insert(int ele){ root = insert(root, ele); } private BinaryNode insert(BinaryNode root, int ele){ //遞歸的結束條件.base condition if(root == null) return new BinaryNode(ele); if(root.ele > ele) root.left = insert(root.left, ele); else if(root.ele < ele) root.right = insert(root.right, ele); else root.left = insert(root.left, ele); return root;//若某結點的左右孩子不空,在后續的遞歸調用中該結點的左右指針是不會變的. } public void zigPrintTree(){ if(root == null) return; LinkedList<BinaryNode> stack = new LinkedList<>();//打印當前行的棧(只保存奇數行的結點) LinkedList<BinaryNode> nextStack = new LinkedList<>();//打印下一行的棧(只保存偶數行的結點) int lineNumber = 1;//標記行號(根為第一行) stack.push(root);//根屬於奇數行的結點(第一行) while(!stack.isEmpty() || !nextStack.isEmpty()) { if(lineNumber % 2 == 1)//奇數行,左孩子先入棧 { while(!stack.isEmpty()) { BinaryNode current = stack.pop(); System.out.print(current);//打印當前結點 if(current.left != null) nextStack.push(current.left);//先左孩子入棧 if(current.right != null) nextStack.push(current.right);//再右孩子入棧 } System.out.println();//該層結點已經打印完,輸出換行符 }else{//偶數行,右孩子先入棧 while(!nextStack.isEmpty()) { BinaryNode current = nextStack.pop(); System.out.print(current); if(current.right != null)//先右孩子入棧 stack.push(current.right); if(current.left != null)//再左孩子入棧 stack.push(current.left); } System.out.println(); } lineNumber++; } } //hapjin test public static void main(String[] args) { int[] eles = {20,10,30,5,12,25,40}; // int[] eles = {20,10,30,12,25}; PrintZigzag pz = new PrintZigzag(); pz.buildTree(eles); pz.zigPrintTree(); } }
(注意:上面構造的是一棵二叉排序樹)
四,參考資料
