当前位置 博文首页 > Inmaturity_7的博客:算法练习帖--36--二叉树的锯齿形层序遍历(J

    Inmaturity_7的博客:算法练习帖--36--二叉树的锯齿形层序遍历(J

    作者:[db:作者] 时间:2021-08-01 11:42

    二叉树的锯齿形层序遍历

    一、题目简介

    给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
    (题目来源:力扣(LeetCode))

    例如:
    给定二叉树 [3,9,20,null,null,15,7],
    
        3
       / \
      9  20
        /  \
       15   7
    返回锯齿形层序遍历如下:
    
    [
      [3],
      [20,9],
      [15,7]
    ]
    

    二、解决方法

    1. BFS+双队列

    package com.lxf.test;
    
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    
    public class ZigzagLevelOrder {
    	public static void main(String[] args) {
    		zigzagLevelOrder(new TreeNode(1));
    	}
        public static  List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        	//表明锯齿在左还是在右
        	boolean flag=true;
        	//存储所有层的list数据
        	List<List<Integer>> lists=new LinkedList<List<Integer>>();
        	//存储当前层数据数据
        	List<Integer> list=new LinkedList<Integer>();
        	//存储树当前层所有节点的链表
        	LinkedList<TreeNode> treeCurNodes=new LinkedList<TreeNode>();
        	//存储树下一层节点的链表
        	LinkedList<TreeNode> treeNextNodes=new LinkedList<TreeNode>();
        	if(root==null) {
        		return lists;
        	}
        	//添加第一个节点
        	treeCurNodes.add(root);
        	//当下一层有节点时就一直遍历
        	while(treeNextNodes!=null) {
        		//现在这一层有节点就遍历获取这一层的值,并存储下一层节点
    			//如果没有直接将从本层切换到下层(下一层没有节点为止)
        		if(treeCurNodes.size()>0) {
        			//将本层的子节点存储到下一层
    				//如果当前层是反序,反插
    				//如果是正序,正插
        			if(flag) {
        				if(treeCurNodes.peek().left!=null) {
            				treeNextNodes.add(treeCurNodes.peek().left);
            			}
            			if(treeCurNodes.peek().right!=null) {
            				treeNextNodes.add(treeCurNodes.peek().right);
            			}
        			}else {
        				if(treeCurNodes.peek().right!=null) {
            				treeNextNodes.add(treeCurNodes.peek().right);
            			}
            			if(treeCurNodes.peek().left!=null) {
            				treeNextNodes.add(treeCurNodes.peek().left);
            			}
        			}
        			//再将当前层当前节点取出并获取它的值
        			list.add(treeCurNodes.poll().val);
        		}else {
        			//切换至下一层
    				//保存本层数据
        			lists.add(list);
        			//重置本层,赋值为下一层
        			treeCurNodes=new LinkedList<TreeNode>();
    				while(treeNextNodes.size()>0) {
    					treeCurNodes.add(treeNextNodes.pollLast());
    				}
    				//切换标志位(获取当前层子节点的顺序)
        			flag=!flag;
    				//重置下一层
        			if(treeCurNodes.size()<1) {
        				treeNextNodes=null;
        			}else {
        				treeNextNodes=new LinkedList<TreeNode>();
        			}
        			//重置存储数据的list
        			list=new ArrayList<Integer>();
        		}
        	}
        	return lists;
        }
    };	
    //       1    cur:3   next:2 3   cur:3 2   flag=false	
    //		/ \   cur:3 2 next:5641  cur: 1465  flag=true
    //	   2  3   cur:1465 next: 78910111213 cur:13121110987 flag=false
    //	  / \  / \
    //	 1	4  6  5
    //  / \  / \  / \ / \
    //  7 8 9 10 11 12 13
    class TreeNode {
         int val;
         TreeNode left;
         TreeNode right;
         TreeNode(int x) { val = x; }
    }
    

    优化:

    package com.lxf.test;
    
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    
    public class ZigzagLevelOrder {
        public static void main(String[] args) {
            TreeNode root = new TreeNode(1);
            TreeNode t2 = new TreeNode(2);
            TreeNode t3 = new TreeNode(3);
            TreeNode t4 = new TreeNode(4);
            TreeNode t5 = new TreeNode(5);
    		root.left=t2;
    		root.right=t3;
    		t2.left=t4;
    		t2.right=t5;
    		List<List<Integer>> lists = zigzagLevelOrder(root);
    		for (List<Integer> list : lists) {
    			for (Integer integer : list) {
    				System.out.print(integer+" ");
    			}
    			System.out.println();
    		}
    	}
    
        public static List<List<Integer>> zigzagLevelOrder(TreeNode root) {
            //表明锯齿在左还是在右
            boolean flag = true;
            //存储所有层的list数据
            List<List<Integer>> lists = new LinkedList<List<Integer>>();
            //存储当前层数据数据
            LinkedList<Integer> list = new LinkedList<Integer>();
            //存储树当前层所有节点的链表
            LinkedList<TreeNode> treeCurNodes = new LinkedList<TreeNode>();
            if (root == null) {
                return lists;
            }
            //添加第一个节点
            treeCurNodes.add(root);
            //当下一层有节点时就一直遍历
            while (!treeCurNodes.isEmpty()) {
                int size = treeCurNodes.size();
                for (int i = 0; i < size; i++) {
                    //将本节点的子节点添加到treeCurNodes中(如果是增强for循环会有问题)
                    if (treeCurNodes.peek().left != null) {
                        treeCurNodes.add(treeCurNodes.peek().left);
                    }
                    if (treeCurNodes.peek().right != null) {
                        treeCurNodes.add(treeCurNodes.peek().right);
                    }
                    //根据标志位进行尾插或者头插
                    if (flag) {
                        list.addLast(treeCurNodes.poll().val);
                    } else {
                        list.addFirst(treeCurNodes.poll().val);
                    }
                }
                //保存本层数据
    			// lists.add(list);这种方法不行,同一对像,到时候一变全便