剑指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)容器中剩余的元素是叶子结点,无左右节点,按顺序从容器中依次取出并打印即可。
综上分析,这种先进先出的容器,是队列,所以我们利用队列做临时存储器来完成打印。

操作步骤图示:

                                                剑指offer:从上往下打印二叉树_第1张图片

从根节点开始打印,如果存在左右子节点,就将左右子节点加入到队列的末尾,然后再从队列头取出元素进行打印,重复进行相同的判断和操作,直到队列中的所有元素都被打印出为止。

代码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 PrintFromTopToBottom(TreeNode root) {
		 ArrayList list=new ArrayList<>();
		 Queue queue=new LinkedList();
		 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 list=ptd.PrintFromTopToBottom(node1);
		System.out.println(list.toString());
	

	}

}

参考博文:https://blog.csdn.net/u013132035/article/details/80604718

这篇博文对二叉树的遍历总结的很全面~~~

博主也总结了对二叉树深度优先遍历的递归和非递归的多种方法,这里再补充一下二叉树后序遍历(非递归的)实现。

//后序遍历:左右根
/*用两个栈来实现:stack1用来记录遍历二叉树的过程,stack用来存储遍历过程中的值*/
	 public void postOrder2(TreeNode root){
		 Stack stack1=new Stack<>();
		 Stack 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+" ");
		 }
		
		
	 }

 

你可能感兴趣的:(剑指offer)