JAVA實現二叉樹的花樣層次遍歷

上一篇文章記錄了二叉樹及N叉樹的前中後序遍歷之後JAVA實現二叉樹、N叉樹遞歸/非遞歸實現前、中、後序遍歷,再來記錄一下二叉樹的花樣層次遍歷,前中後序遍歷非遞歸主要藉助這一數據結構,層次遍歷主要是藉助隊列這一數據結構。
這三道題目有點進階打怪的意思,哈哈~~從最簡單的層次遍歷開始;再到要求每層輸出爲一行,就需要知道每層有幾個節點了;再到要求之字形打印,那麼不只需要知道每層有幾個節點,還有要知道當前遍歷到那一層了。具體分析如下:


題目解答中用到的TreeNode類,定義如下:

public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

從上往下打印二叉樹

題目描述:

從上往下打印出二叉樹的每個節點,同層節點從左至右打印。

題目解答:

  • 由題目描述可以知道這裏考察的是二叉樹的層次遍歷

  • 利用隊列:先進先出的特性,首先將根節點入隊;

  • 判斷當隊不爲空的時候,隊頭元素出隊,放入list集合,然後將其左孩子入隊,然後將其右孩子入隊;

  • 注意root爲空的情況

    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
              ArrayList<Integer> list = new ArrayList<Integer>();
            if (root == null){
                return list;
            }
           Queue<TreeNode> queue = new LinkedList<TreeNode>();
           queue.add(root);
            TreeNode topNode;
            while (!queue.isEmpty()){
                topNode = queue.remove();
                list.add(topNode.val);
                if (topNode.left != null){
                  queue.add(topNode.left);
                }
                if (topNode.right != null){
                   queue.add(topNode.right);
                }
            }
            return list;
        }
    

把二叉樹打印成多行

題目描述:

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

題目解答:

  • 相對於層次遍歷的區別在於:每層輸出一行;

  • 即需要知道每一層的節點個數,將遍歷的節點放入list,該行遍歷結束之後,將list放入res

  • 問題在於如何知道每一層的節點個數?首先知道當前所在層的個數,在遍歷當前所在層的時候,計算出下一層的節點個數,當前層遍歷結束,更新當前層的節點個數爲下一層的節點個數。

    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
            ArrayList<ArrayList<Integer>> res = new ArrayList<>();
            if (pRoot == null ){
                return res;
            }
            Queue<TreeNode> q = new LinkedList<>();
            q.offer(pRoot);
            //記錄每一層的節點個數
            int sum = 1;
            while (!q.isEmpty()){
                ArrayList<Integer> list = new ArrayList<>();
                //當前所在層下一層節點的個數
                int temp = 0;
              while (sum>0){
                  TreeNode node = q.remove();
                      list.add(node.val);
                      if (node.left != null){
                          q.offer(node.left);
                          temp++;
                      }
                      if (node.right != null){
                          q.offer(node.right);
                          temp ++;
                      }
                  sum --;
              }
              //當前所在層節點操作完成之後,更新sum的值,進行下一層
              sum = temp;
               res.add(list);
            }
            return res;
        }
    

按之字形順序打印二叉樹

題目描述:

請實現一個函數按照之字形打印二叉樹,即第一行按照從左到右的順序打印,第二層按照從右至左的順序打印,第三行按照從左到右的順序打印,其他行以此類推。

題目解答:

  • 與把二叉樹打印成多行相比,區別在於相鄰行的打印順序不同

  • 需要知道當前所在行是第幾行,若當前行是偶數行需要對list集合進行順序調整

    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
            ArrayList<ArrayList<Integer>> res = new ArrayList<>();
    
            if (pRoot == null){
                return res;
            }
            Queue<TreeNode> q = new LinkedList<>();
            q.offer(pRoot);
            //當前所操作的行數
            int row = 1;
            //每層的節點數
            int sum = 1;
            while (!q.isEmpty()){
                ArrayList<Integer> list = new ArrayList<>();
                //當前所在層的下一層節點的個數
                int temp = 0;
                //遍歷當前層的所有節點
                while (sum>0){
                    //將隊首元素出隊
                    TreeNode node = q.remove();
                    list.add(node.val);
    
                    if (node.left != null){
                        q.offer(node.left);
                        temp++;
                    }
    
                    if (node.right != null){
                        q.offer(node.right);
                        temp ++;
                    }
                    sum--;
                }
                sum = temp;
                if (row % 2 ==0){
                    //當前行是偶數行的的話,需要將獲得的list數組調整
                    for (int i = 0,j = list.size()-1;i<j;i++,j--){
                        int t = list.get(i);
                        list.set(i,list.get(j));
                        list.set(j,t);
                    }
                }
                row++;
                res.add(list);
            }
            return res;
            
        }
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章