1. 程式人生 > >二叉樹14:把二叉樹列印成多行

二叉樹14:把二叉樹列印成多行

題目:從上到下按層列印二叉樹,同一層結點從左至右輸出。每一層輸出一行。

思路:按層列印,使用按層遍歷(寬度優先遍歷)即可,需要使用一個佇列(通過LinkedList來充當佇列),然後進行迴圈即可,如果不需要考慮換行,那麼十分簡單。如果需要考慮換行,那麼關鍵就是確定何時進行換行,如何確定換行?使用2個指標last和nlast來分別指向下一行的最後一個結點合當前正在訪問(不是遍歷,是指壓入佇列的元素)的最後一個結點。初始時,認為初始指標在頭結點的上方空間,此時令last=root;nlast=null,然後進行按層遍歷,每次從佇列中彈出一個結點temp表示當前遍歷到的結點,要與下一行的最後一個結點last進行比較,看是否相同,如果相同就換行,否則繼續;每次從佇列中彈出一個結點後需要將其2個子節點進行判斷並壓入佇列中,將nlast指向當前壓入佇列的結點,如果temp==last,表示正在遍歷的結點已經到達行的結尾,此時必然恰好該temp的第二個子節點就是下一行的最後一個結點,於是將nlast賦值給last對last進行更新即可。每一行遍歷結束後就新建一個ArrayList即可。

常識:建立集合時不要使用介面List,如果使用List,那麼list就是List型別的,於是不能使用poll等方法,即變數總是使用它的靜態型別作為其真正的型別(jvm)。

import java.util.*;
//按層遍歷,使用last,nlast指標來進行換行
public class Solution {
    //使用成員變數來存放結果集合,也可以作為引數傳入到方法中
    ArrayList<ArrayList<Integer>> results;
    ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
        //建立一個ArrayList<ArrayList<Integer> >用於存放答案
        results=new ArrayList<ArrayList<Integer>>();
        //呼叫一個單獨的方法解決問題,仔細:這裡傳入的引數是pRoot而不是root
        //特殊輸入:要注意空節點輸入的情況:此時返回的是一個空的list而不是null
        if(pRoot==null) return results;
        this.process(pRoot);
        //返回結果
        return results;
    }
    
    //輸入一棵二叉樹,按層遍歷,將每一層的結點放入一個ArrayList中
    private void process(TreeNode root){
        //①建立一個佇列
        LinkedList<TreeNode> queue=new LinkedList<>();
        ArrayList<Integer> list=new ArrayList<>();
        //②建立輔助的變數指標last和nlast
        TreeNode last=root;
        TreeNode nlast=null;
        //③先將根結點root放入到佇列中
        queue.add(root);
        //開始迴圈:彈出--遍歷--壓入左右子孩子--判斷是否到層的結尾
        while(queue.size()!=0){
            //彈出遍歷一個結點
            TreeNode temp=queue.poll();
            //int放入Integer中,會自動裝箱
            list.add(temp.val);
            //先壓入左右子孩子並更新nlast
            if(temp.left!=null){
                queue.add(temp.left);
                nlast=temp.left;
            }
            if(temp.right!=null){
                queue.add(temp.right);
                nlast=temp.right;
            }
            //判斷當前遍歷的結點是否到達層的最後結尾
            if(last==temp){
                //到達層的最後一個結點,更新last
                last=nlast;
                //此時換一個新的list來存放每層的結點,並將當前層的list放入到結果集中
                results.add(list);
                list=new ArrayList<Integer>();
            }
        }
    }
}