習慣github pages風格的請看我的另一篇博客
題目32:從上到下打印二叉樹
- 不分行從上到下打印二叉樹
- 分行從上到下打印二叉樹
- 之字形打印二叉樹
題目 1. 不分行從上到下打印二叉樹
從上到下打印出二叉樹的每個節(jié)點,同一層的節(jié)點按照從左到右的順序打印。
二叉樹結(jié)點
public static class BinaryTreeNode {
int value;
BinaryTreeNode left;
BinaryTreeNode right;
public BinaryTreeNode(){
}
public BinaryTreeNode(int value){
this.value = value;
}
}
舉例說明
如下的二叉樹
8
/ \
6 10
/ \ / \
5 7 9 11
則依次打印出8 6 10 5 7 9 11
解題思路
考查樹的遍歷算法。
從上到下打印二叉樹的規(guī)律:
- 每一次打印一個結(jié)點的時候,如果該結(jié)點有子結(jié)點, 則把該結(jié)點的
子結(jié)點放到一個隊列的末尾 - 接下來到隊列的
頭部取出最早進入隊列的結(jié)點 - 重復前面的打印操作,直至隊列中
所有的結(jié)點都被打印出來為止
代碼實現(xiàn):
import java.util.Queue;
import java.util.LinkedList;
public class _3200{
public static class BinaryTreeNode {
int value;
BinaryTreeNode left;
BinaryTreeNode right;
public BinaryTreeNode(){
}
public BinaryTreeNode(int value){
this.value = value;
}
}
public static void printFromTopToBottom(BinaryTreeNode root) {
if (root != null) { // 當結(jié)點非空時才進行操作
// 用于存放還未遍歷的元素
Queue<BinaryTreeNode> list = new LinkedList<>();
list.add(root); // 根結(jié)點入隊
BinaryTreeNode cur; // 當前處理的結(jié)點
while (!list.isEmpty() ) {
cur = list.remove(); // 刪除隊首
System.out.print(cur.value + " "); // 輸出隊首元素的值
// 如果左子結(jié)點不為空,則左子結(jié)點入隊
if (cur.left != null) {
list.add(cur.left);
}
// 如果右子結(jié)點不為空,則左子結(jié)點入隊
if (cur.right != null) {
list.add(cur.right);
}
}
}
}
public static void main(String[] args) {
// 8
// / \
// 6 10
// / \ / \
// 5 7 9 11
BinaryTreeNode n1 = new BinaryTreeNode(8);
BinaryTreeNode n2 = new BinaryTreeNode(6);
BinaryTreeNode n3 = new BinaryTreeNode(10);
BinaryTreeNode n4 = new BinaryTreeNode(5);
BinaryTreeNode n5 = new BinaryTreeNode(7);
BinaryTreeNode n6 = new BinaryTreeNode(9);
BinaryTreeNode n7 = new BinaryTreeNode(11);
n1.left = n2;
n1.right = n3;
n2.left = n4;
n2.right = n5;
n3.left = n6;
n3.right = n7;
printFromTopToBottom(n1);
}
}

不分行從上到下打印二叉樹
擴展:
- 從上到下按層遍歷二叉樹,從本質(zhì)上來說就是
廣度優(yōu)先遍歷二叉樹 - 不管是廣度優(yōu)先遍歷一幅有向圖還是一棵樹,都要用到
隊列 - 首先把
起始節(jié)點(樹中為根結(jié)點)放入隊列,接下來每次從隊列的頭部取出一個節(jié)點,遍歷這個節(jié)點后把它能到達的節(jié)點(樹中為子結(jié)點)都依次放入隊列。重復這個遍歷過程,直到隊列中的節(jié)點全部都遍歷為止
題目 2. 分行從上到下打印二叉樹
從上到下按層打印二叉樹,同一層的節(jié)點按從左到右的順序打印,每一層打印到一行。
舉例說明
如下的二叉樹
8
/ \
6 10
/ \ / \
5 7 9 11
則依次打印出
8
6 10
5 7 9 11
解題思路
用隊列來保存要打印的節(jié)點。
同時我們需要兩個變量:一個變量表示在當前層中還沒有打印的節(jié)點數(shù);另一個變量表示下一層節(jié)點的數(shù)目
代碼實現(xiàn)
import java.util.LinkedList;
import java.util.List;
public class _3201{
public static class BinaryTreeNode {
int value;
BinaryTreeNode left;
BinaryTreeNode right;
public BinaryTreeNode(){
}
public BinaryTreeNode(int value){
this.value = value;
}
}
public static void print(BinaryTreeNode root) {
if (root == null) {
return;
}
List<BinaryTreeNode> list = new LinkedList<>();
BinaryTreeNode node;
int current = 1;// 當前層的結(jié)點個數(shù),開始時只有根節(jié)點一個
int next = 0;// 下一層的結(jié)點個數(shù)
list.add(root);
while (list.size() > 0) {
node = list.remove(0);
current--;
System.out.print(" "+node.value);
if (node.left != null) {
list.add(node.left);
next++;
}
if (node.right != null) {
list.add(node.right);
next++;
}
if (current ==0) {
System.out.println();//本層打印完了
current = next;//現(xiàn)在處理下一層
next = 0;
}
}
}
public static void main(String[] args) {
// 8
// / \
// 6 10
// / \ / \
// 5 7 9 11
BinaryTreeNode n1 = new BinaryTreeNode(8);
BinaryTreeNode n2 = new BinaryTreeNode(6);
BinaryTreeNode n3 = new BinaryTreeNode(10);
BinaryTreeNode n4 = new BinaryTreeNode(5);
BinaryTreeNode n5 = new BinaryTreeNode(7);
BinaryTreeNode n6 = new BinaryTreeNode(9);
BinaryTreeNode n7 = new BinaryTreeNode(11);
n1.left = n2;
n1.right = n3;
n2.left = n4;
n2.right = n5;
n3.left = n6;
n3.right = n7;
print(n1);
}
}

分行從上到下打印二叉樹
題目 3. 之字形打印二叉樹
請實現(xiàn)一個函數(shù)按照之字形打印二叉樹,即第一行按照從左到右的順序打印,第二層按照從右至左的順序打印,第三行按照從左到右的順序打印,其他行以此類推。(每一層打印到一行。)
舉例說明
如下的二叉樹
8
/ \
6 10
/ \ / \
5 7 9 11
則依次打印出
8
10 6
5 7 9 11
解題思路
按之字形順序打印二叉樹需要兩個棧。
- 我們在打印某一行結(jié)點時,把下一層的子結(jié)點保存到相應的棧里
- 如果當前打印的是奇數(shù)層,則先保存左子結(jié)點再保存右子結(jié)點到一個棧里
- 如果當前打印的是偶數(shù)層,則先保存右子結(jié)點再保存左子結(jié)點到第二個棧里
代碼實現(xiàn)
import java.util.LinkedList;
import java.util.List;
public class _3202{
public static class BinaryTreeNode {
int value;
BinaryTreeNode left;
BinaryTreeNode right;
public BinaryTreeNode(){
}
public BinaryTreeNode(int value){
this.value = value;
}
}
public static void print(BinaryTreeNode root) {
if (root == null) {
return;
}
List<BinaryTreeNode> current = new LinkedList<>();
List<BinaryTreeNode> reverse = new LinkedList<>();
int flag = 0;//bool flag = false;
BinaryTreeNode node;
current.add(root);
while (current.size() > 0) {
// 從最后一個開始取,相當于棧
node = current.remove(current.size() - 1);
System.out.print(" "+node.val);
if (flag == 0) {// if (!flag ) // 當前是從左往右打印的,那就按從左往右入棧
if (node.left != null) {
reverse.add(node.left);
}
if (node.right != null) {
reverse.add(node.right);
}
}else { // 當前是從右往左打印的,那就按從右往左入棧
if (node.right != null) {
reverse.add(node.right);
}
if (node.left != null) {
reverse.add(node.left);
}
}
if (current.size() == 0) {//當前層處理完了
flag = 1 - flag;//flag != ;
List<BinaryTreeNode> tmp = current;
current = reverse;
reverse = tmp;
System.out.println();
}
}
}
public static void main(String[] args) {
// 8
// / \
// 6 10
// / \ / \
// 5 7 9 11
BinaryTreeNode n1 = new BinaryTreeNode(8);
BinaryTreeNode n2 = new BinaryTreeNode(6);
BinaryTreeNode n3 = new BinaryTreeNode(10);
BinaryTreeNode n4 = new BinaryTreeNode(5);
BinaryTreeNode n5 = new BinaryTreeNode(7);
BinaryTreeNode n6 = new BinaryTreeNode(9);
BinaryTreeNode n7 = new BinaryTreeNode(11);
n1.left = n2;
n1.right = n3;
n2.left = n4;
n2.right = n5;
n3.left = n6;
n3.right = n7;
print(n1);
}
}

之字形打印二叉樹