按之字形順序打印二叉樹
http://blog.csdn.net/qq_27703417/article/details/70977347
請實現一個函數按照之字形打印二叉樹,即第一行按照從左到右的順序打印,第二層按照從右至左的順序打印,第三行按照從左到右的順序打印,其他行以此類推
第一行的時候,控制的是第二行的打印順序,第二行的時候,控制的是第三行的打印順序
奇數行從左到右壓入棧,所以下一行按逆序打印
偶數行從右到左壓入棧,所以下一行按正序打印
創建2個棧stack1和stack2,先將root結點壓入到stack1中,然後開始循環過程:從stack1中彈出root,每次彈出一個結點時要判斷它的左右子節點是否是null,如果不為null就壓入到另一個棧stack2中,即這裏彈出結點的棧和壓入子節點的棧應該是分開的2個棧,從stack1中彈出的結點它的子節點要壓入到另一個棧stack2中,當stack1中的結點彈光後,先判斷stack2裏面的元素是否為空,如果stack2中的結點數目也為0,那麽說明在stack1彈出結點的時候沒有再壓入子節點到stack2中,說明此時已經沒有下一層了,於是遍歷結束,即遍歷循環結束的判斷條件是:stack1.isEmpty()並且stack2.isEmpty()。Stack1彈完後這一層就遍歷結束了,它的下一層的結點都在stack2中了,為了便於循環中的操作,將stack2賦值給stack1,將stack2重新創建,這樣就始終只要對stack1進行彈出,對stack2進行壓入操作了,在循環代碼中的實現較為簡單。即基本操作過程就是從stack1中彈出結點,並將結點的子節點放入到另一個棧stack2中,當stack1遍歷結束後就將stack2賦值給stack1,並將stack2重建,直到stack1和stack2都變空為止。需要註意的是:對於每一層,要求打印的順序是不同的,對於奇數層,要求從左到右遍歷結點,對於偶數層要求從右到左遍歷結點,如何實現?對於偶數層,例如②③,在彈出時是先彈出③再彈出②,此時為了使得它的下一層能夠從左到右輸出,應該使得對於彈出的結點,先將其右孩子放入棧stack2,在將左孩子放入stack2,於是stack2中先後壓入⑦⑥⑤④,彈出時的順序就是④⑤⑥⑦;同理對於奇數層的結點,例如第三層,在遍歷時的順序是④⑤⑥⑦,它的下一層要求遍歷順序是15,14,13,12,11,⑩⑨⑧,於是在對④⑤⑥⑦的子節點壓入棧是應該先壓入左孩子再壓入右孩子,於是先後向stack2中壓入⑧⑨⑩11,12,13,14,15.總結來說,
- import java.util.*;
- //之字形遍歷:使用2個棧,遍歷先壓入左結點再壓入右結點和先右結點再左結點交替進行;自動換行,不用last和nlast
- public class Solution {
- //創建結果集,成員變量
- ArrayList<ArrayList<Integer>> results;
- public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
- results=new ArrayList<ArrayList<Integer>>();
- //特殊輸入
- if(pRoot==null) return results;
- //調用方法解決問題
- this.process(pRoot);
- //返回結果集
- return results;
- }
- //該方法用來之字形遍歷二叉樹,並將每層結果放入到results中
- private void process(TreeNode root){
- //①創建輔助棧
- Stack<TreeNode> stack1=new Stack<>();
- Stack<TreeNode> stack2=new Stack<>();
- //每一層的結果集
- ArrayList<Integer> list=new ArrayList<>();
- //第一變量記錄層數
- int levelCount=1;
- //②先將root壓入棧
- stack1.push(root);
- //③循環:彈棧遍歷--左右孩子入棧--交換stack1和stack2
- //只要stack1和stack2不全為空就可以繼續
- while(!(stack1.isEmpty()&&stack2.isEmpty())){
- //彈出並遍歷
- TreeNode temp=stack1.pop();
- list.add(temp.val);
- //左右孩子壓入stack2中
- if(levelCount%2!=0){
- //奇數層,先左再右
- if(temp.left!=null){
- stack2.push(temp.left);
- }
- if(temp.right!=null){
- stack2.push(temp.right);
- }
- }else{
- //偶數層,先右再左
- if(temp.right!=null){
- stack2.push(temp.right);
- }
- if(temp.left!=null){
- stack2.push(temp.left);
- }
- }
- //判斷此時stack1是否為空,即本層是否遍歷完成
- if(stack1.isEmpty()){
- //本層遍歷完成:換list,換stack1和stack2;層數加1
- results.add(list);
- list=new ArrayList<Integer>();
- stack1=stack2;
- stack2=new Stack<TreeNode>();
- //千萬記得層數+1
- levelCount++;
- }
- }
- }
- }
按之字形順序打印二叉樹