- 剑指 Offer 面试题 60(Java 版):把二叉树打印成多行
题目:从上到下按层打印二叉树,同一层的结点按从左到右的顺序打印,每一层打印一行。
思路:用一个队列来保存将要打印的结点。为了把二叉树的每一行单独打印到一行里,我们需要两个变量:一个变量表示在当前的层中还没有打印的结点数,另一个变量表示下一次结点的数目。
show my code
/**
* 按行打印二叉树
* @author innovator
*
*/
public class PrintTree {
/**
* 按照层来打印二叉树
* @param root
*/
public static void printTreeByLine(BinaryTreeNode root){
if(root == null){
return;
}
//用队列来装遍历到的节点
Queue queue = new LinkedList<>();
queue.add(root);
//下一层节点数目
int nextLevel = 0;
//当前层中未被打印的节点数
int toBePrinted = 1;
while(!queue.isEmpty()){
BinaryTreeNode current = queue.peek();
//打印当前节点
System.out.printf(" %d",current.value);
//层序遍历
if(current.leftNode != null){
queue.add(current.leftNode);
nextLevel ++;
}
if(current.rightNode != null){
queue.add(current.rightNode);
nextLevel ++;
}
//弹出当前节点,出队
queue.poll();
toBePrinted --;
//当前层已经打印完毕
if(toBePrinted == 0){
//输出换行
System.out.printf("\n");
//从下层开始打印
toBePrinted = nextLevel;
nextLevel = 0;
}
}
}
// 8
// 6 10
// 5 7 9 11
public static void main(String[] args){
BinaryTreeNode root = new BinaryTreeNode(8);
BinaryTreeNode node1 = new BinaryTreeNode(6);
BinaryTreeNode node2 = new BinaryTreeNode(10);
BinaryTreeNode node3 = new BinaryTreeNode(5);
BinaryTreeNode node4 = new BinaryTreeNode(7);
BinaryTreeNode node5 = new BinaryTreeNode(9);
BinaryTreeNode node6 = new BinaryTreeNode(11);
root.leftNode = node1;
root.rightNode = node2;
node1.leftNode = node3;
node1.rightNode = node4;
node2.leftNode = node5;
node2.rightNode = node6;
printTreeByLine(root);
}
}
- 剑指 Offer 面试题 61(Java 版):按之字形顺序打印二叉树
题目:请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,即第一行按照从左到右的顺序打印,第二层按照从右到左顺序打印,第三行再按照从左到右的顺序打印,其他以此类推。
思路:按之字形顺序打印二叉树需要两个栈。我们在打印某一行结点时,把下一层的子结点保存到相应的栈里。如果当前打印的是奇数层,则先保存左子结点再保存右子结点到一个栈里;如果当前打印的是偶数层,则先保存右子结点再保存左子结点到第二个栈里。
show my code
/**
* 按照之字顺序打印二叉树
* @author innovator
*
*/
public class PrintTreeByZHI {
/**
* 按照之字顺序打印二叉树
* @param root
*/
public static void printTree(BinaryTreeNode root){
if(root == null){
return;
}
//存放奇数层的结点
Stack stack1 = new Stack<>();
//存放偶数层的结点
Stack stack2 = new Stack<>();
//是否在打印奇数层
int printFlag = 1;
BinaryTreeNode current;
stack1.push(root);
//还有结点在栈中未打印
while(!stack1.isEmpty() || !stack2.isEmpty()){
if(printFlag == 1){
current = stack1.pop();
}else{
current = stack2.pop();
}
System.out.printf(" "+ current.value);
//将下一层的结点入栈
if(printFlag == 1){
//压入偶数栈
//先左后右
if(current.leftNode != null){
stack2.push(current.leftNode);
}
if(current.rightNode != null){
stack2.push(current.rightNode);
}
}else{
//压入奇数栈
//先右后左
if(current.rightNode != null){
stack1.push(current.rightNode);
}
if(current.leftNode != null){
stack1.push(current.leftNode);
}
}
//打印完了奇数层,轮到偶数层了
//加了前面的判断是为了防止当下一行为空的时候,会跑进去打印换行,打印完了当前的栈才允许切换flag
if(printFlag == 1 && stack1.isEmpty()){
System.out.printf("\n");
printFlag = 0;
}
//打印完了偶数层,轮到奇数层了
if(printFlag == 0 && stack2.isEmpty()){
System.out.printf("\n");
printFlag = 1;
}
}
}
// 8
// 6 10
// 5 7 9 11
public static void main(String[] args){
BinaryTreeNode root = new BinaryTreeNode(8);
BinaryTreeNode node1 = new BinaryTreeNode(6);
BinaryTreeNode node2 = new BinaryTreeNode(10);
BinaryTreeNode node3 = new BinaryTreeNode(5);
BinaryTreeNode node4 = new BinaryTreeNode(7);
BinaryTreeNode node5 = new BinaryTreeNode(9);
BinaryTreeNode node6 = new BinaryTreeNode(11);
root.leftNode = node1;
root.rightNode = node2;
node1.leftNode = node3;
node1.rightNode = node4;
node2.leftNode = node5;
node2.rightNode = node6;
printTree(root);
}
}