二叉树的层次遍历
2016-03-14 20:21
260 查看
1 利用递归
第一种方法,就是利用递归的方法,按层进行打印,我们把根节点当做第0层,之后层次依次增加,如果我们想打印第二层怎么办呢,利用递归的代码如下://打印指定level的节点的val public int print_at_level(TreeNode root, int level, ArrayList<Integer> aList) { if(root == null || level <0){ return 0; } //向下计算,只有当level == 0 的时候才是寻到了指定层的节点,这个时候才将root的值加入到打印链表 if(level == 0){ aList.add(root.val); return 1; } int left = print_at_level(root.left, level-1, aList); int right = print_at_level(root.right, level-1, aList); return left + right; }
如果我们成功的打印了给定的层次,那么就返回非0的正值,如果失败返回0。有了这个思路,我们就可以应用一个循环,来打印这颗树的所有层的节点,但是有个问题就是我们不知道这棵二叉树的深度,怎么来控制循环使其结束呢,仔细看一下print_at_level,如果指定的Tree是空的,那么就直接返回0,当返回0的时候,我们就结束循环,说明没有节点可以打印了:
int count = 0; //从第0层(root)开始打印,直到没有下一层了为止 while(true){ if(sol.print_at_level(root, count, aList) == 0){ break; } count++; } for (Integer integer : aList) { System.out.println(integer); } System.out.printf("The depth of this tree is : %d", count);
结果:
以上的方法可以很清楚的看出,存在重复访问的情况,就是第0层访问的次数最多,第1层次之。所以这个递归的方法不是很有效的方法。
2 利用队列
从上往下,每一层从左往右遍历;root入队;
每次取队首的节点,将它不为null的子节点加入队列中,然后打印首节点的值;
直到队列为空。
public void printByLevel_Queue(TreeNode root, ArrayList<Integer> aList) { LinkedList<TreeNode> queue = new LinkedList<TreeNode>(); if(root == null){ return; } queue.add(root); TreeNode p; do { p = queue.removeFirst(); aList.add(p.val); if(p.left != null){ queue.add(p.left); } if (p.right != null) { queue.add(p.right); } } while (!queue.isEmpty()); }
3 Binary Tree Level Order Traversal
Given a binary tree, return the level order traversal of its nodes’ values. (ie, from left to right, level by level).For example:
Given binary tree {3,9,20,#,#,15,7},
return its level order traversal as:
3.1 利用上面的递归算法
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<List<Integer>> levelOrder(TreeNode root) { ArrayList<Integer> levelList; ArrayList<List<Integer>> treeList = new ArrayList<List<Integer>>(); if(root == null){ return treeList; } int count = 0; while(true){ levelList = new ArrayList<Integer>(); if(printByLevel_Recursively(root, count, levelList) == 0){ break; } else { count ++; treeList.add(levelList); } } return treeList; } //打印指定level的节点的val public int printByLevel_Recursively(TreeNode root, int level, ArrayList<Integer> aList) { if(root == null || level <0){ return 0; } //向下计算,只有当level == 0 的时候才是寻到了指定层的节点,这个时候才将root的值加入到打印链表 if(level == 0){ aList.add(root.val); return 1; } int left = printByLevel_Recursively(root.left, level-1, aList); int right = printByLevel_Recursively(root.right, level-1, aList); return left + right; } }
3.2 利用队列
在section 2 介绍的方法的基础上,只是加了一个 parentCount 来这一层的节点数量,和一个 childrenCount 来记录下一层的节点数量:/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<List<Integer>> levelOrder(TreeNode root) { ArrayList<Integer> levelList; ArrayList<List<Integer>> treeList = new ArrayList<List<Integer>>(); if(root == null){ return treeList; } LinkedList<TreeNode> queue = new LinkedList<TreeNode>(); int parentCount = 1; int childrenCount = 0; queue.add(root); TreeNode tmp; levelList = new ArrayList<Integer>(); do { tmp = queue.removeFirst(); parentCount--; levelList.add(tmp.val); if(tmp.left != null){ queue.add(tmp.left); childrenCount++; } if(tmp.right != null){ queue.add(tmp.right); childrenCount++; } if(parentCount == 0){ parentCount = childrenCount; childrenCount = 0; treeList.add(levelList); levelList = new ArrayList<Integer>(); } } while (!queue.isEmpty()); return treeList; } }
4 Binary Tree Level Order Traversal II
Given a binary tree, return the bottom-up level order traversal of its nodes’ values. (ie, from left to right, level by level from leaf to root).For example:
Given binary tree {3,9,20,#,#,15,7},
return its bottom-up level order traversal as:
我认为,无非就是section 3 中的方法最后加一个逆序。如果网友有更好的方法请留言,谢谢。
相关文章推荐
- AVL树-自平衡二叉查找树(Java实现)
- C语言二叉树的非递归遍历实例分析
- 使用C语言构建基本的二叉树数据结构
- 一波二叉树遍历问题的C++解答实例分享
- C++非递归队列实现二叉树的广度优先遍历
- C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法
- C#非递归先序遍历二叉树实例
- C++将二叉树转为双向链表及判断两个链表是否相交
- C++非递归建立二叉树实例
- C语言实现找出二叉树中某个值的所有路径的方法
- C++实现二叉树遍历序列的求解方法
- C语言实现二叉树遍历的迭代算法
- C++实现查找二叉树中和为某一值的所有路径的示例
- 用C语言判断一个二叉树是否为另一个的子结构
- C++实现二叉树非递归遍历方法实例总结
- C++二叉树结构的建立与基本操作
- 深入遍历二叉树的各种操作详解(非递归遍历)
- JavaScript数据结构和算法之二叉树详解
- java使用归并删除法删除二叉树中节点的方法
- Java中二叉树数据结构的实现示例