new lee103 按之字形顺序打印二叉树 stack看懂了不知道错在哪

7 篇文章 0 订阅
4 篇文章 0 订阅

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

lee上大神操作 用两个stack

1.遍历第二层的节点的顺序是从左到右,而输出第二层节点的顺序是从右到左,这正好满足栈思想,所有用栈来第二层所有节点。
2.遍历栈输出第二层节点,同时还需要将第三层的节点按照从右到左的顺序存储。但是不能将第三层的节点存储到这个栈中,因为会打乱第二层节点的顺序,此时我们可以想到创建另一个栈来存储第三层的元素。这样层与层之间就不会产生干扰。
3.交替使用这两个栈遍历所有的层。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
    	List<List<Integer>> list = new ArrayList<>();
        if (root == null) {
        	return list;
        }
        //栈1来存储右节点到左节点的顺序
        Stack<TreeNode> stack1 = new Stack<>(); 
        //栈2来存储左节点到右节点的顺序
        Stack<TreeNode> stack2 = new Stack<>();
        
        //根节点入栈
    	stack1.push(root);
    	
    	//每次循环中,都是一个栈为空,一个栈不为空,结束的条件两个都为空
        while (!stack1.isEmpty() || !stack2.isEmpty()) {
        	List<Integer> subList = new ArrayList<>(); // 存储这一个层的数据
        	TreeNode cur = null;
        	
        	if (!stack1.isEmpty()) { //栈1不为空,则栈2此时为空,需要用栈2来存储从下一层从左到右的顺序
        		while (!stack1.isEmpty()) {	//遍历栈1中所有元素,即当前层的所有元素
        			cur = stack1.pop();
        			subList.add(cur.val);	//存储当前层所有元素
        			
        			if (cur.left != null) {	//左节点不为空加入下一层
        				stack2.push(cur.left);
        			}
        			if (cur.right != null) {	//右节点不为空加入下一层
        				stack2.push(cur.right);
        			}
        		}
        		list.add(subList);
        	}else {//栈2不为空,则栈1此时为空,需要用栈1来存储从下一层从右到左的顺序
        		while (!stack2.isEmpty()) {
        			cur = stack2.pop();
        			subList.add(cur.val);
        			
        			if (cur.right != null) {//右节点不为空加入下一层
        				stack1.push(cur.right);
        			}
        			if (cur.left != null) { //左节点不为空加入下一层
        				stack1.push(cur.left);
        			}
        		}
        		list.add(subList);
        	}
        }
        return list;
    }
}

我写的,有问题 看不出来

class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> res=new ArrayList<>();
        if(root==null) return res;
        Stack<TreeNode> stack1 = new Stack<>();
        Stack<TreeNode> stack2 = new Stack<>();
        stack1.push(root);
        while(!stack1.isEmpty() || !stack2.isEmpty()){
           
            List<Integer> list=new ArrayList<>();
            TreeNode cur=null;
            if(!stack1.isEmpty()){
                while(!stack1.isEmpty()){
                        
                    cur=stack1.pop();
                    list.add(cur.val);

                    if(cur.left!=null){
                        stack2.push(cur.left);
                    }  
                    if(cur.right!=null){
                        stack2.push(cur.right);
                    }
                }
                res.add(list);
            }else{
                while(!stack2.isEmpty()){
                    cur=stack2.pop();
                    list.add(cur.val);
                    if(cur.left!=null){
                        stack1.push(cur.left);
                    }  
                    if(cur.right!=null){
                        stack1.push(cur.right);
                    }
                }
                res.add(list);
            }    
        }
        return res;
    }
}

不太优雅
看别人的:

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if (root == null) return res;
        Stack<TreeNode> stack1 = new Stack<>();
        Stack<TreeNode> stack2 = new Stack<>();
        stack1.push(root);
        int count = 1;
        while (!stack1.isEmpty() || !stack2.isEmpty()) {
            ArrayList<Integer> list = new ArrayList<>();
            if (count % 2 == 1) {//取出来,先存左儿子,再存右儿子
                while (!stack1.isEmpty()) {
                    TreeNode tmp = stack1.pop();
                    list.add(tmp.val);
                    if (tmp.left != null) stack2.push(tmp.left);
                    if (tmp.right != null) stack2.push(tmp.right);
                }
            } else {//取出来,先存右儿子,再存左儿子
                while (!stack2.isEmpty()) {
                    TreeNode tmp = stack2.pop();
                    list.add(tmp.val);
                    if (tmp.right != null) stack1.push(tmp.right);
                    if (tmp.left != null) stack1.push(tmp.left);
                }
            }
            count++;
            res.add(list);
        }
        return res;
    }
}

前序遍历递归

可以这么写:

class Solution {
    List<List<Integer>> res=new ArrayList<>();
    public List<List<Integer>> levelOrder(TreeNode root) {
        helper(root,0);
        return res;
    }

    private void helper(TreeNode root,int level){
        if(root==null)
            return;
        if(res.size()==level){
            res.add(new ArrayList<>());
        }
        if(level%2==0){
            res.get(level).add(root.val);

        }else{
            res.get(level).add(0,root.val);
        }
        helper(root.left,level+1);
        helper(root.right,level+1);
    }
}

这个也比较麻烦 算了思路

大家的实现很多都是将每层的数据存进ArrayList中,偶数层时进行reverse操作,
在海量数据时,这样效率太低了。
(我有一次面试,算法考的就是之字形打印二叉树,用了reverse,
直接被鄙视了,面试官说海量数据时效率根本就不行。)

  • 下面的实现:不必将每层的数据存进ArrayList中,偶数层时进行reverse操作,直接按打印顺序存入
  • 思路:利用Java中的LinkedList的底层实现是双向链表的特点。
    1)可用做队列,实现树的层次遍历
    2)可双向遍历,奇数层时从前向后遍历,偶数层时从后向前遍历
public class Solution {
 
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
        }
        if (node.left != null) {
            queue.addLast(node.left);
        }
        if (node.right != null) {
            queue.addLast(node.right);
        }
    } 
    return ret;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值