您的位置:首页 > 其它

二叉树的层次遍历

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 中的方法最后加一个逆序。如果网友有更好的方法请留言,谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二叉树 层次遍历