1. 程式人生 > >演算法--分奇偶行列印二叉樹--佇列的應用

演算法--分奇偶行列印二叉樹--佇列的應用

頭條的一道面試題,層序列印二叉樹,奇數行時從左到右,偶數行時從右到左。

如上所示,列印結果為 :

  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++;
		}
	}

在出隊的同時,保留佇列中元素值,同時當出對節點左右子節點非空時也要繼續入隊,這裡提前需要有一個變數來記錄上一行中節點數並依次遞減來計數。