上一篇文章記錄了二叉樹及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; }