遍历二叉树的三种情况-java实现

遍历二叉树,从上往下遍历。但是同层节点可以从左向右遍历,也可以从右向左遍历(也就是之字型遍历),其中,都需要队列进行实现。只是按照之字型稍微麻烦一些。

(1)从上往下打印出二叉树的每个节点,同层节点从左至右打印。

需要一个队列,队列里面放节点(从根节点开始),然后依次进行打印。

import java.util.ArrayList;
import java.util.Queue;
import java.util.LinkedList;
class  TreeNode{
    int  val = 0;
    TreeNode   left = null;
    TreeNode   right = null;

    public   TreeNode(int  val){
        this.val  =  val;
    }
}

public class Solution {
     public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
         ArrayList<Integer> list = new ArrayList<Integer>();
         if(root == null) 
             return list;
         Queue<TreeNode>   queue =  new LinkedList<TreeNode>();

         queue.add(root);
         while(!queue.isEmpty()){
             TreeNode   t  =   queue.poll();
             list.add(t.val);
             if(t.left != null) queue.add(t.left);
             if(t.right != null) queue.add(t.right);
         }
         return list;
     }
}

(2)请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

解析:之字形打印二叉树,不要将所有层放入ArrayList中后再将偶数层进行reverse(),这样可以实现,但是数据量大的时候效率太低。

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
 class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}

public class Solution {
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>>   result=new ArrayList<ArrayList<Integer>>();
        if(pRoot==null){
            return result;
        }

        Queue<TreeNode>   queue = new LinkedList<TreeNode>();
        int rows=1;
        queue.add(pRoot);
        while(!queue.isEmpty()){
           ArrayList<Integer>   list=new ArrayList();
            int size=queue.size();
            for(int i=0;i<size;i++){
                TreeNode t=queue.poll();
                if(rows%2==0){
                    list.add(0,t.val);  //将元素插入指定位置(头部),也就相当于倒序了
                }else{
                    list.add(t.val);  //将元素插入尾部
                }
                if(t.left!=null){
                    queue.offer(t.left);
                }
                if(t.right!=null){
                    queue.offer(t.right);
                }
            }
            result.add(list);
            rows++;
        }
        return result;

    }

}

(3)从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
这道题就是典型的二叉树层次遍历。
思路:因为我们要按层打印,所以需要设置标志量。
其次:我们需要三个集合:
第一个集合用于存放结果集
第二个集合用于临时存放每一层的结果,等到一层结束之后,再将其加入到最终结果集中。注意,每一次使用完这个集合之后,需要将其清空,以便下一次存放。
第三个集合用于存放节点。


import java.util.ArrayList;
import java.util.LinkedList;
import java.util.*;

class TreeNode
{
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val)
    {
        this.val = val;

    }

}

public class Solution
{
    ArrayList<ArrayList<Integer>> Print(TreeNode pRoot)
    {

        ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();

        ArrayList<Integer> arrayList = new ArrayList<Integer>();

        Queue<TreeNode> queue = new LinkedList<TreeNode>(); // 存放节点

        // 检查是否为空
        if (pRoot == null)
            return result;

        queue.add(pRoot);

        int start = 0;
        int end = 1; // 第一行

        while (!queue.isEmpty())
        {
            TreeNode treeNode = queue.poll();
            end--;
            arrayList.add(treeNode.val);

            if (treeNode.left != null) // 如果有左节点
            {
                queue.add(treeNode.left);// 将左节点加入linkedList中
                start++; // 标志进入下一行
            }
            if (treeNode.right != null)
            {
                queue.add(treeNode.right);
                start++; // 标志进入下一行
            }

            if (end == 0)
            { // 此时也就是说明把一层已经打印完了,应该将其加入结果集中
                result.add(new ArrayList<Integer>(arrayList)); // 加入结果集中
                arrayList.clear();// 必须将临时存放结果的集合清空,以便进行下一次存放
                end = start; // 恢复原状
                start = 0;

            }

        }

        return result;

    }

}


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值