二叉树分层Z字形遍历

原题

  Given a binary tree, return the zigzag level order traversal of its nodes’ values. (ie, from left to right, then right to left for the next level and alternate between).
  For example:
  Given binary tree {3,9,20,#,#,15,7},

    3
   / \
  9  20
    /  \
   15   7

 

return its zigzag level order traversal as:

[
  [3],
  [20,9],
  [15,7]
]

 

 

题目大意

  给定一棵二叉树,从顶向下,进行Z字形分层遍历,即:如果本层是从左向右的,下层就是从右向左。

解题思路

  二叉树分层遍历进行改进,使用两个栈来进行。

代码实现

树结点类

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}

 

算法实现类

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


public class Solution {

    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> result = new LinkedList<>();

        if (root == null) {
            return result;
        }
        // 遍历标志,0表示从左到右,1表示从右到左
        int flag = 0;
        TreeNode node;
        // 记录每一层的元素
        List<Integer> lay = new LinkedList<>();
        // 双向队列,当作栈来使用,记录当前层待处理结点
        Deque<TreeNode> stack = new LinkedList<>();
        // 记录下一层待处理结点
        Deque<TreeNode> nextStack = new LinkedList<>();

        stack.add(root);

        while (!stack.isEmpty()) {
            // 删除栈顶元素
            node = stack.removeLast();

            // 结果入队
            lay.add(node.val);

            // 如果当前是从左到右遍历,按左子树右子树的顺序添加
            if (flag == 0) {
                if (node.left != null) {
                    nextStack.addLast(node.left);
                }

                if (node.right != null) {
                    nextStack.addLast(node.right);
                }
            }
            // 如果当前是从右到左遍历,按右子树左子树的顺序添加
            else {
                if (node.right != null) {
                    nextStack.addLast(node.right);
                }

                if (node.left != null) {
                    nextStack.addLast(node.left);
                }
            }

            // 当前层已经处理完了
            if (stack.isEmpty()) {
                Deque<TreeNode> temp = nextStack;
                nextStack = stack;
                stack = temp;

                // 标记下一层处理的方向
                flag = 1 - flag;
                // 保存本层结果
                result.add(lay);
                // 创建新的链表处理下一层的结果
                lay = new LinkedList<>();
            }
        }

        return result;
    }
}

 

解题思路:
这题和第102题解法类似,对102题的方法进行改造,使用两个Deque来实现,第一个Deque()实现本层的遍历,第二个Deque()实现下层节点的输入。

二,AC了的程序(采用Java程序)

import java.util.*;
class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x)
    {
        val=x;
    }
}

public class Test2 {

    List<List<Integer>> list=new ArrayList<List<Integer>>();  //leetcode 103
    public List<List<Integer>> zigzagLevelOrder(TreeNode root)
    {
         if(root==null)
         {
             return list;
         }

        //LinkedList<TreeNode> queue=new LinkedList<TreeNode>();  //定义LinkedList类型

        //queue.offer(root);  // 首先把根节点入队列

        boolean temp1=false;  //temp1=false表示从左到右遍历,temp2=true表示从右到左遍历
        Deque<TreeNode> queue=new LinkedList<TreeNode>();//Deque是双向队列,双向队列是指该队列两端的元素既能够入队,也能出队
        Deque<TreeNode> nextqueue=new LinkedList<TreeNode>(); //记录下一层待处理结点

        queue.add(root); //首先先把二叉树的根进入双端队列
        List<Integer> templist=new LinkedList<Integer>();  //templist为临时的集;
        while(!queue.isEmpty())  //该双端队列不为空的
        {

            TreeNode node=queue.removeLast();//删除
            templist.add(node.val);  //把节点值加入到临时集

            if(temp1==false)  //如果当前是从左到右遍历的,那么下一层要从左到右添加节点
            {
                if(node.left!=null)
                {
                    nextqueue.addLast(node.left);
                }
                if(node.right!=null)
                {
                    nextqueue.addLast(node.right);
                }
            }
            else //当前是从右到左遍历的,那么下层就要从右到左添加节点的。
            {
                if(node.right!=null)
                {
                    nextqueue.addLast(node.right);
                }
                if(node.left!=null)
                {
                    nextqueue.addLast(node.left);
                }

            }

            if(queue.isEmpty())  //如果当前这层已经变为空了
            {
                Deque<TreeNode> temp=nextqueue; //就把下一层节点复制给当前节点,下一层的Deque边为空的
                nextqueue=queue; //下一层deque变为空的。
                queue=temp;

                temp1=(temp1==false)?true:false;

                list.add(templist);
                templist=new LinkedList<Integer>();


            }


        }

        return list;

    }


    public static void main(String []args)
    {
        Test2 test=new Test2();

        TreeNode root=new TreeNode(3);
        TreeNode p2=new TreeNode(9);
        TreeNode p3=new TreeNode(20);
        TreeNode p4=new TreeNode(15);
        TreeNode p5=new TreeNode(7);
        TreeNode p6=new TreeNode(4);
        TreeNode p7=new TreeNode(5);

        root.left=p2;
        root.right=p3;
        p3.left=p4;
        p3.right=p5;
        p5.left=p6;
        p5.right=p7;


         /*
        TreeNode root=new TreeNode(1);
        TreeNode p2=new TreeNode(2);
        TreeNode p3=new TreeNode(3);
        TreeNode p4=new TreeNode(4);
        TreeNode p5=new TreeNode(5);

        root.left=p2;
        root.right=p3;
        p2.left=p4;
        p3.right=p5;
        */

        List<List<Integer>> list=test.zigzagLevelOrder(root);
        Iterator<List<Integer>> it1=list.iterator();
        while(it1.hasNext())
        {
            List<Integer> list2=it1.next();
            Iterator<Integer> it2=list2.iterator();
            while(it2.hasNext())
            {
                int data=it2.next();
                System.out.print(data+" ");
            }
            System.out.println();
        }

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133

运行结果:
这里写图片描述

转载于:https://my.oschina.net/u/2822116/blog/808776

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值