剑指offer:从上往下打印二叉树
题目描述
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
实际考察树的层次遍历(广度优先遍历)算法,从上往下遍历二叉树,本质上就是广度优先遍历二叉树。
10
/ \
6 14
/\ /\
4 8 12 16
用按层遍历二叉树的方法,
(1)按层遍历的顺序决定首先应该打印根节点,所以从根节点10开始分析。
(2)打印完根节点10,要打印它的左右子节点6,14。所以在遍历到左右子节点时,先将它们装入容器中,此时容器内存了6,14
(3) 先打印左节点6,此时6的左右子节点4,8也进入了容器,容器内有3个元素,14,4,8
(4)从容器内取出14并打印,然后将14的左右子节点12,16存入容器中,此时容器中有4个元素,按顺序是4,8,12,16
(5)容器中剩余的元素是叶子结点,无左右节点,按顺序从容器中依次取出并打印即可。
综上分析,这种先进先出的容器,是队列,所以我们利用队列做临时存储器来完成打印。
操作步骤图示:
从根节点开始打印,如果存在左右子节点,就将左右子节点加入到队列的末尾,然后再从队列头取出元素进行打印,重复进行相同的判断和操作,直到队列中的所有元素都被打印出为止。
代码1:
package com.day02;
import java.util.ArrayList;
import java.util.Queue;
import java.util.LinkedList;
//定义树结构
class TreeNode{
int val;
TreeNode left;
TreeNode right;
TreeNode(int x){
this.val=x;
}
}
class PrinTreeDemo {
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
ArrayList<Integer> list=new ArrayList<>();
Queue<TreeNode> queue=new LinkedList<TreeNode>();
if(root==null){
return list;
}
queue.offer(root);
while(!queue.isEmpty()){
TreeNode node=queue.poll();//移除并返回队列头部的元素
System.out.println(node.val);
list.add(node.val);
if(node.left!=null){
queue.offer(node.left);//offer():向队列 添加元素并返回true
}
if(node.right!=null){
queue.offer(node.right);
}
}
return list;
}
//设置指定根节点左孩子和右孩子的方法
public static void SetSubTreeNode(TreeNode root,TreeNode lChild,TreeNode rChild){
if(root==null){
return;
}
root.left=lChild;
root.right=rChild;
}
//测试代码
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeNode node1=new TreeNode(10);
TreeNode node2=new TreeNode(16);
TreeNode node3=new TreeNode(14);
TreeNode node4=new TreeNode(4);
TreeNode node5=new TreeNode(8);
TreeNode node6=new TreeNode(12);
TreeNode node7=new TreeNode(16);
SetSubTreeNode(node1,node2,node3);
SetSubTreeNode(node2,node4,node5);
SetSubTreeNode(node3,node6,node7);
PrinTreeDemo ptd=new PrinTreeDemo();
ArrayList<Integer> list=ptd.PrintFromTopToBottom(node1);
System.out.println(list.toString());
}
}
参考博文:https://blog.****.net/u013132035/article/details/80604718
这篇博文对二叉树的遍历总结的很全面~~~
博主也总结了对二叉树深度优先遍历的递归和非递归的多种方法,这里再补充一下二叉树后序遍历(非递归的)实现。
//后序遍历:左右根
/*用两个栈来实现:stack1用来记录遍历二叉树的过程,stack用来存储遍历过程中的值*/
public void postOrder2(TreeNode root){
Stack<TreeNode> stack1=new Stack<>();
Stack<TreeNode> stack2=new Stack<>();
while(root!=null||!stack1.isEmpty()){
while(root!=null){
stack1.push(root);
stack2.push(root);
root=root.right;
}
root=stack1.pop();
root=root.left;
}
while(!stack2.isEmpty()){
System.out.println(stack2.pop().val+" ");
}
}