演算法--分奇偶行列印二叉樹--佇列的應用
阿新 • • 發佈:2018-12-16
頭條的一道面試題,層序列印二叉樹,奇數行時從左到右,偶數行時從右到左。
如上所示,列印結果為 :
1
3 2
4 5 6 7
10 9 8
1. 普通的層序列印二叉樹,一般採用一個佇列,根節點入佇列,然後一次遍歷佇列中的節點,列印每一個節點值,同時若該節點左右節點非空,繼續入佇列:
public static void levelOrder(TreeNode root){ if(root==null) return; Queue<TreeNode> q = new LinkedList<>(); q.add(root); TreeNode tmp = null; while(!q.isEmpty()){ tmp = q.poll(); System.out.println(tmp.val); if(tmp.left!=null) q.add(tmp.left); if(tmp.right!=null) q.add(tmp.right); } }
2.剛開始我的解法是進行一遍BFS,把二叉樹的遍歷結果儲存在一個List<List<Integer>>,其中二叉樹的每一行對應List<List>的每一個元素List,然後遍歷這個List<List>即可實現各種型別的列印效果,程式碼如下:
public static void levelOrder2(TreeNode root){ List<List<Integer>> ll = new ArrayList<>(); bfs(root, ll, 0); System.out.println(ll); for(int i=0; i<ll.size(); i++){ if(((i+1)&0x01)==1){ System.out.println(ll.get(i)); }else{ List<Integer> l = ll.get(i); Collections.reverse(l); System.out.println(l); } } } public static void bfs(TreeNode node, List<List<Integer>> ll, int depth){ if(node==null) return; if(depth>=ll.size()){ List<Integer> l = new ArrayList<>(); l.add(node.val); ll.add(l); }else{ ll.get(depth).add(node.val); } bfs(node.left, ll, depth+1); bfs(node.right, ll, depth+1); }
這樣做空間複雜度太大,需要把原來二叉樹給複製一遍,後來又提示了一下,採用佇列方式來實現。把每一行全部入隊,然後分奇偶行來列印二叉樹:
public static void levelOrder3(TreeNode root){ if(root==null) return; Queue<TreeNode> q = new LinkedList<>(); q.add(root); int level = 1; while(!q.isEmpty()){ List<Integer> l = new ArrayList<>(); int size = q.size(); while(size>0){ TreeNode tmp = q.poll(); l.add(tmp.val); if(tmp.left!=null) q.add(tmp.left); if(tmp.right!=null) q.add(tmp.right); size--; } if((level&0x01)==1){ System.out.println(l); }else{ Collections.reverse(l); System.out.println(l); } level++; } }
在出隊的同時,保留佇列中元素值,同時當出對節點左右子節點非空時也要繼續入隊,這裡提前需要有一個變數來記錄上一行中節點數並依次遞減來計數。