题目:
不分行从上到下打印二叉树。
从上到下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印。
分析:
这里就是按照层次遍历,我们需要一个队列来辅助完成遍历。
每次打印一个结点的时候,如果该结点有子结点,则把该结点的子结点放到一个队列的末尾。接下来到队列的头部取出最早进入队列的结点,重复前面的打印操作,直至队列中所有的结点都被打印出来。
解法:
package com.wsy;
import java.util.LinkedList;
import java.util.Queue;
class Tree {
private int value;
private Tree left;
private Tree right;
public Tree() {
}
public Tree(int value) {
this.value = value;
this.left = this.right = null;
}
public Tree(int value, Tree left, Tree right) {
this.value = value;
this.left = left;
this.right = right;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Tree getLeft() {
return left;
}
public void setLeft(Tree left) {
this.left = left;
}
public Tree getRight() {
return right;
}
public void setRight(Tree right) {
this.right = right;
}
}
public class Main {
public static void main(String[] args) {
Tree tree = init();
print(tree);
}
public static Tree init() {
Tree tree1 = new Tree(8);
Tree tree2 = new Tree(6);
Tree tree3 = new Tree(10);
Tree tree4 = new Tree(5);
Tree tree5 = new Tree(7);
Tree tree6 = new Tree(9);
Tree tree7 = new Tree(11);
tree1.setLeft(tree2);
tree1.setRight(tree3);
tree2.setLeft(tree4);
tree2.setRight(tree5);
tree3.setLeft(tree6);
tree3.setRight(tree7);
return tree1;
}
public static void print(Tree tree) {
if (tree == null) {
return;
}
Queue<Tree> queue = new LinkedList<Tree>();
queue.add(tree);
while (!queue.isEmpty()) {
tree = queue.poll();
System.out.print(tree.getValue() + "\t");
if (tree.getLeft() != null) {
queue.add(tree.getLeft());
}
if (tree.getRight() != null) {
queue.add(tree.getRight());
}
}
}
}
题目:
分行从上到下打印二叉树。
从上到下按层打印二叉树,同一层的结点按照从左到右的顺序打印,每一层打印到一行。
分析:
我们需要加入两个变量:一个变量表示当前层中还没有打印的结点数,另一个变量表示下一层结点的数目。
变量toBePrint表示当前层还没有打印的结点数,变量nextLevel表示下一层的结点数。如果一个结点有子结点,每把一个子结点加入队列,同时把变量nextLevel加1。每打印一个结点,toBePrint减1。当toBePrint变成0时,表示当前层的所有结点已经打印完毕,可以继续打印下一层了。
解法:
package com.wsy;
import java.util.LinkedList;
import java.util.Queue;
class Tree {
private int value;
private Tree left;
private Tree right;
public Tree() {
}
public Tree(int value) {
this.value = value;
this.left = this.right = null;
}
public Tree(int value, Tree left, Tree right) {
this.value = value;
this.left = left;
this.right = right;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Tree getLeft() {
return left;
}
public void setLeft(Tree left) {
this.left = left;
}
public Tree getRight() {
return right;
}
public void setRight(Tree right) {
this.right = right;
}
}
public class Main {
public static void main(String[] args) {
Tree tree = init();
print(tree);
}
public static Tree init() {
Tree tree1 = new Tree(8);
Tree tree2 = new Tree(6);
Tree tree3 = new Tree(10);
Tree tree4 = new Tree(5);
Tree tree5 = new Tree(7);
Tree tree6 = new Tree(9);
Tree tree7 = new Tree(11);
tree1.setLeft(tree2);
tree1.setRight(tree3);
tree2.setLeft(tree4);
tree2.setRight(tree5);
tree3.setLeft(tree6);
tree3.setRight(tree7);
return tree1;
}
public static void print(Tree tree) {
if (tree == null) {
return;
}
Queue<Tree> queue = new LinkedList<Tree>();
queue.add(tree);
int nextLevel = 0;
int toBePrint = 1;
while (!queue.isEmpty()) {
tree = queue.poll();
System.out.print(tree.getValue() + "\t");
if (tree.getLeft() != null) {
queue.add(tree.getLeft());
nextLevel++;
}
if (tree.getRight() != null) {
queue.add(tree.getRight());
nextLevel++;
}
toBePrint--;
if (toBePrint == 0) {
System.out.println("");
toBePrint = nextLevel;
nextLevel = 0;
}
}
}
}
题目:
之字形打印二叉树。
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二行按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
分析:
当二叉树根节点1打印之后,它的左结点2和右结点3先后保存到一个数据容器里。在打印第二层结点时,先打印结点3,再打印结点2。因此这个数据容器可以用栈来实现。
在打印第三层的时候,先打印2的子结点(结点4和结点5),再打印结点3的子结点(结点6和结点7),结点4,5和结点6,7对于结点3,结点2也是反着的,所以也可以用栈来实现。用一个栈保存结点2和结点3的子结点。
第三层结点是从左向右打印的,按照4->5->6->7的顺序,所以7先入栈,接着是6,5,4。在打印第二层结点的时候,先把右子结点保存到栈里,再把左子结点保存到栈里。
打印第三层结点的同时,需要把第四层结点保存到一个栈里。由于第四层的打印顺序是从右到左,因此保存的顺序是先保存左子结点,再保存右子结点。
按照之字形顺序打印二叉树需要两个栈。在打印某一层结点时,把下一层的子结点保存到相应的栈里。如果当前打印的是奇数层,则先保存左子结点再保存右子结点到第一个栈里,如果当前打印的是偶数层,则先保存右子结点再保存左子结点到第二个栈里。
如果这里只用一个栈,打印根节点时候,先后把结点2,结点3保存到栈中。接下来打印结点3,会把结点6,结点7保存到栈中,此时,结点7就位于栈顶了,而不是结点2,此时就乱了。
解法:
package com.wsy;
import java.util.Stack;
class Tree {
private int value;
private Tree left;
private Tree right;
public Tree() {
}
public Tree(int value) {
this.value = value;
this.left = this.right = null;
}
public Tree(int value, Tree left, Tree right) {
this.value = value;
this.left = left;
this.right = right;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Tree getLeft() {
return left;
}
public void setLeft(Tree left) {
this.left = left;
}
public Tree getRight() {
return right;
}
public void setRight(Tree right) {
this.right = right;
}
}
public class Main {
public static void main(String[] args) {
Tree tree = init();
print(tree);
}
public static Tree init() {
Tree tree15 = new Tree(15);
Tree tree14 = new Tree(14);
Tree tree13 = new Tree(13);
Tree tree12 = new Tree(12);
Tree tree11 = new Tree(11);
Tree tree10 = new Tree(10);
Tree tree9 = new Tree(9);
Tree tree8 = new Tree(8);
Tree tree7 = new Tree(7, tree14, tree15);
Tree tree6 = new Tree(6, tree12, tree13);
Tree tree5 = new Tree(5, tree10, tree11);
Tree tree4 = new Tree(4, tree8, tree9);
Tree tree3 = new Tree(3, tree6, tree7);
Tree tree2 = new Tree(2, tree4, tree5);
Tree tree1 = new Tree(1, tree2, tree3);
return tree1;
}
public static void print(Tree tree) {
if (tree == null) {
return;
}
Stack<Tree> stack0 = new Stack<>();
Stack<Tree> stack1 = new Stack<>();
boolean odd = true;
stack1.push(tree);
while (!stack0.empty() || !stack1.empty()) {
if (odd) {
tree = stack1.pop();
System.out.print(tree.getValue() + "\t");
if (tree.getLeft() != null) {
stack0.push(tree.getLeft());
}
if (tree.getRight() != null) {
stack0.push(tree.getRight());
}
if (stack1.empty()) {
odd = !odd;
System.out.println();
}
} else {
tree = stack0.pop();
System.out.print(tree.getValue() + "\t");
if (tree.getRight() != null) {
stack1.push(tree.getRight());
}
if (tree.getLeft() != null) {
stack1.push(tree.getLeft());
}
if (stack0.empty()) {
odd = !odd;
System.out.println();
}
}
}
}
}