从上往下打印出二叉树的每个节点,同层节点从左至右打印.
思路:通过举例子画图,明白了用队列来存储点,当打印当前点的时候,判断当前有子节点吗?有,就将子节点加入队列,无,就不加。
但是这里并不打算详细介绍这个,而是2道变式题。
1.分行从上到下打印二叉树。
8 8
6 10 / \
5 7 9 12 6 10
/ \ / \
5 7 9 12
思路:同样是利用队列来保存打印节点的次序,但是,这里面需要处理的是必须能标记每一层的节点值。每一层打印完必须换行,每一层有几个,几个才算打印完。一个就是当前层还需要打印的节点个数,和下一层需要打印的节点数。
思路首先定义 int tobePrint = 1,int nextLevel = 0;
先加入root进队列,然后打印当前的根节点,再判断当前的root.left和right的子节点不为空就加入队列同时nextLevel++,再把刚才打印的root节点处队列,同时tobePrint--,一定保持这个顺序。同时再判断if(tobePrint==0),为0 tobePrint与nextLevel交换变量值.
但是为什么nextLevel能保持正确的值,当前一层的节点值由tobePrint决定,而当我们处理当前的节点时,如果它有子节点的话,nextLvel++,这样当前层的所有子节点都会被处理进队列,当前层的tobePrint为0,便会处理下一层的情况了。
代码:
class BinaryTreeNode {
int value;
BinaryTreeNode left;
BinaryTreeNode right;
public BinaryTreeNode(int value) {
this.value = value;
left = null;
right = null;
}
}
void print(BinaryTreeNode proot){
if(proot==null){
return;
}
//定义一个队列,双端队列而已
Queue<BinaryTreeNode> queue = new LinkedList<>();
((LinkedList<BinaryTreeNode>) queue).push(proot);
//2个变量初始化
int nextLevel = 0;
int toBePrinted = 1;
//不为空继续
while(!queue.isEmpty()){
BinaryTreeNode node = ((LinkedList<BinaryTreeNode>) queue).getLast();
//打印
System.out.println(node.value);
if(node.left!=null){
((LinkedList<BinaryTreeNode>) queue).push(node.left);
++nextLevel;
}
if(node.right!=null){
((LinkedList<BinaryTreeNode>) queue).push(node.right);
++nextLevel;
}
//这个时候出队列
((LinkedList<BinaryTreeNode>) queue).pop();
//同时减少需要被打印的节点数
--toBePrinted;
//如果toBePrinted为0换行,并nextLevel赋值给toBePrinted。nextLevel = 0.
//如果不为0,证明当前行还未输出完。继续while循环输出队列的值
if(toBePrinted==0){
System.out.println();
toBePrinted = nextLevel;
nextLevel = 0;
}
}
}