算法练习帖--36--二叉树的锯齿形层序遍历(Java)

二叉树的锯齿形层序遍历

一、题目简介

给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
(题目来源:力扣(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);这种方法不行,同一对像,到时候一变全便
            lists.add(new ArrayList<>(list));
            //切换标志位
            flag = !flag;
            //重置存储数据的list
            list.clear();
        }
        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;
    }
}

2. BFS+双端队列

package com.lxf.test;

import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

class Solution {
    
    
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
    
    
        List<List<Integer>> ans = new LinkedList<List<Integer>>();
        if (root == null) {
    
    
            return ans;
        }

        Queue<TreeNode> nodeQueue = new LinkedList<TreeNode>();
        nodeQueue.offer(root);
        boolean isOrderLeft = true;

        while (!nodeQueue.isEmpty()) {
    
    
            //存储当前层值得双端队列
            Deque<Integer> levelList = new LinkedList<Integer>();
            //当前层的长度
            int size = nodeQueue.size();
            for (int i = 0; i < size; ++i) {
    
    
                //当前层当前节点
                TreeNode curNode = nodeQueue.poll();
                //isOrderLeft:true-->反插
                //isOrderLeft:true-->正插
                if (isOrderLeft) {
    
    
                    levelList.offerLast(curNode.val);
                } else {
    
    
                    levelList.offerFirst(curNode.val);
                }
                //获取下一层节点
                if (curNode.left != null) {
    
    
                    nodeQueue.offer(curNode.left);
                }
                if (curNode.right != null) {
    
    
                    nodeQueue.offer(curNode.right);
                }
            }
            ans.add(new LinkedList<Integer>(levelList));
            isOrderLeft = !isOrderLeft;
        }

        return ans;
    }
}

猜你喜欢

转载自blog.csdn.net/Inmaturity_7/article/details/111528480