简单算法 按之字形顺序打印二叉树(java)

这篇博客介绍了两种方法来实现二叉树的之字形层序遍历。第一种利用两个栈,分别存储奇数层和偶数层节点,交替进行遍历;第二种方法借助LinkedList的双向遍历特性,通过切换正反遍历来达到目标。这两种方法都有效地解决了问题,展示了Java在处理树结构遍历上的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单算法 按之字形顺序打印二叉树(java)
描述
给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
例如:
给定的二叉树是{1,2,3,#,#,4,5}

该二叉树之字形层序遍历的结果是
[
[1],
[3,2],
[4,5]
]
想法:找两个栈分别储存奇数偶数层的二叉树结点

代码:

import java.util.ArrayList;
import java.util.*;
/*
public 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>> list = new ArrayList<ArrayList<Integer>>();
        Stack<TreeNode> s1 = new Stack<TreeNode>();
        s1.push(pRoot);//将头结点放入奇数层
        Stack<TreeNode> s2 = new Stack<TreeNode>();
        int flag = 1;//判断在奇数层还是偶数层所用
        while(!s1.empty() || !s2.empty()){
            if(flag % 2 != 0){
                //判断在奇数层
                ArrayList<Integer> a1 = new ArrayList<Integer>();//储存结点上的数
                while(!s1.empty()){//把s1所有结点取出找到下一层结点并放入s2
                    TreeNode t1 = s1.pop();
                    if(t1 != null){
                        a1.add(t1.val);
                    s2.push(t1.left);
                    s2.push(t1.right);
                    }
                }
                if(!a1.isEmpty()){//判断a1是否有值,有值加入list
                    list.add(a1);
                    flag++;
                }
            }else{
                    //判断在偶数层
                ArrayList<Integer> a2 = new ArrayList<Integer>();//储存结点上的数
                while(!s2.empty()){//把s2所有结点取出找到下一层结点并放入s1
                    TreeNode t1 = s2.pop();
                    if(t1 != null){
                    a2.add(t1.val);
                    s1.push(t1.right);//这里顺序变了,因为是之字型遍历
                    s1.push(t1.left);
                    }
                }
                if(!a2.isEmpty()){//判断a2是否有值,有值加入list
                    list.add(a2);
                    flag++;
                }
            }
            }
            return list;
        }
    }

然后我又看见了一个利用LinkList集合可以正反遍历来实现:
思路:利用Java中的LinkedList的底层实现是双向链表的特点。
可用做队列,实现树的层次遍历
可双向遍历,奇数层时从前向后遍历,偶数层时从后向前遍历

public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
   ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
   if (pRoot == null) {
       return ret;
   }
   ArrayList<Integer> list = new ArrayList<>();
   LinkedList<TreeNode> queue = new LinkedList<>();
   queue.addLast(null);//层分隔符
   queue.addLast(pRoot);
   boolean leftToRight = true;
    
   while (queue.size() != 1) {
       TreeNode node = queue.removeFirst();
       if (node == null) {//到达层分隔符
           Iterator<TreeNode> iter = null;
           if (leftToRight) {
               iter = queue.iterator();//从前往后遍历
           } else {
               iter = queue.descendingIterator();//从后往前遍历
           }
           leftToRight = !leftToRight;
           while (iter.hasNext()) {
               TreeNode temp = (TreeNode)iter.next();
               list.add(temp.val);
           }
           ret.add(new ArrayList<Integer>(list));
           list.clear();
           queue.addLast(null);//添加层分隔符
           continue;//一定要continue,到了这里因为是null分隔层所以不必找它是否有左右结点,直接跳过下面代码的这次循环
       }
       if (node.left != null) {
           queue.addLast(node.left);
       }
       if (node.right != null) {
           queue.addLast(node.right);
       }
   }
    
   return ret;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值