问题:给定一个二叉树,要求按分层遍历该二叉树,即从上到下按层次访问该二叉树(每一层将单独输出一行),每一层要求访问的顺序为从左到右,并将节点依次编号。那么分层遍历如图的二叉树,正确的输出应该为:
<span style="font-size:14px;">1 2 3 4 5 6 7 8</span>
书中还给出了问题2:打印二叉树中的某层次的节点(从左到右),其中根结点为第0层,成功返回true,失败返回false
分析与解法
关于二叉树的问题,由于其本身固有的递归特性,通常可以用递归解决。为了解决给出的问题,我们可以发现。当解决问题2时,问题就迎刃而解了。现先分析问题2
假设要访问二叉树第K层的节点,那么其实可以把它转换为分别访问“已该二叉树根结点的左右子节点为根结点的两颗子树”中层次为k-1的节点。如题目中的二叉树,给定k=2,即要求访问原二叉树中第2层的节点(根结点为第0层),可以把它转换为分别访问以节点2、3为根结点的两颗子树中的k-1=1层的节点。
所以遍历第k层节点的代码如下(把最终结果存放在了list里):
public boolean printNodeAtLevel(TreeNode root, int level, List<Integer> list) { <span style="white-space:pre"> </span>if (root == null || level < 0) { <span style="white-space:pre"> </span>return false; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>if (level == 0 && root != null) { <span style="white-space:pre"> </span>list.add(root.val); <span style="white-space:pre"> </span>return true; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>boolean left = printNodeAtLevel(root.left, level-1, list); <span style="white-space:pre"> </span>boolean rigth = printNodeAtLevel(root.right, level-1, list); <span style="white-space:pre"> </span>return left || rigth; }
public int maxDepth(TreeNode root) { if (root == null) { return 0; } int left = 1+maxDepth(root.left); int rigth = 1+maxDepth(root.right); return left > rigth ? left : rigth; }好了,问题就解决了。好像发现这样的效率太低了。把求深度和遍历某层次的代码合并,得到如下代码:
public List<List<Integer>> levelOrder2(TreeNode root) { List<List<Integer>> lists = new ArrayList<List<Integer>>(); if (root == null) return lists; for (int level = 0; ; level++) { List<Integer> list = new ArrayList<>(); if (!printNodeAtLevel(root, level, list)) break; lists.add(0, list); } return lists; }
public List<List<Integer>> levelOrder3(TreeNode root) { List<List<Integer>> lists = new ArrayList<List<Integer>>(); if (root == null) return lists; int cur = 0, last = 1; List<TreeNode> queue = new ArrayList<>(); queue.add(root); while (cur < queue.size()) { last = queue.size(); List<Integer> list = new ArrayList<>(); while (cur < last) { TreeNode node = queue.get(cur); list.add(node.val); if (node.right != null) { queue.add(node.right); } if (node.left != null) { queue.add(node.left); } cur++; } lists.add(list); } return lists; }
方法一,是用了两个队列,一个队列存储k-1层的节点,另一个队列存储k层的节点。代码如下:
public List<List<Integer>> levelOrder1(TreeNode root) { List<List<Integer>> lists = new ArrayList<List<Integer>>(); if (root == null) return lists; LinkedList<TreeNode> preQueue = new LinkedList<>(); LinkedList<TreeNode> curQueue = new LinkedList<>(); preQueue.offer(root); curQueue.offer(root); while (!curQueue.isEmpty()) { List<Integer> list = new ArrayList<>(); while (!curQueue.isEmpty()) { TreeNode node = curQueue.poll(); list.add(node.val); } lists.add(list); while (!preQueue.isEmpty()) { TreeNode node = preQueue.poll(); if (node.left != null) { curQueue.offer(node.left); } if (node.right != null) { curQueue.offer(node.right); } } preQueue = new LinkedList<>(curQueue); } return lists; }
public List<List<Integer>> levelOrder4(TreeNode root) { List<List<Integer>> lists = new ArrayList<List<Integer>>(); if (root == null) return lists; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { int levelNum = queue.size(); List<Integer> list = new LinkedList<>(); for (int i = 0; i < levelNum; i++) { TreeNode node = queue.poll(); if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } list.add(node.val); } lists.add(0, list); } return lists; }
原文:http://blog.csdn.net/my_jobs/article/details/43452159