按之字形顺序打印二叉树(java版)

来源:互联网 发布:自学编程 编辑:程序博客网 时间:2024/06/15 06:27

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


【解题思路1】
//1.使用两个栈来分别存储奇数层节点和偶数层节点。
//2.注意两个栈的插入顺序是不同的。
//3.对于奇数层来说,也就是从左往右的顺序,先添加左子树,然后添加右子树。对于偶数层,刚好相反,先添加右子树,然后添加左子树。

import java.util.ArrayList;import java.util.Stack;public class Solution {    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {        int level = 1;        //s1存奇数层节点        Stack<TreeNode> s1 = new Stack<TreeNode>();        s1.push(pRoot);        //s2存偶数层节点        Stack<TreeNode> s2 = new Stack<TreeNode>();        ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();        while (!s1.empty() || !s2.empty()) {            if (level%2 != 0) {                ArrayList<Integer> temp = new ArrayList<Integer>();                while (!s1.empty()) {                    TreeNode node = s1.pop();                    if(node != null) {                        temp.add(node.val);                        s2.push(node.left);                        s2.push(node.right);                    }                }                if (!temp.isEmpty()) {                    list.add(temp);                    level++;                    }            } else {                    ArrayList<Integer> temp = new ArrayList<Integer>();                    while (!s2.empty()) {                        TreeNode node = s2.pop();                        if(node != null) {                            temp.add(node.val);                            s1.push(node.right);                            s1.push(node.left);                        }                    }                    if (!temp.isEmpty()) {                        list.add(temp);                        level++;                    }                }            }        return list;    }}

【解题思路2】
//1. 层序遍历
//2.当遍历到奇数层时,从左到右存储该层遍历的值。当遍历到偶数层时,从右到左存储该层遍历的值。

public class Solution {    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {        ArrayList<ArrayList<Integer>> layers = new ArrayList<ArrayList<Integer>>();        if (pRoot == null)            return layers;        Deque<TreeNode> queue = new LinkedList<TreeNode>();        queue.offer(pRoot);        int depth = 0;        while (!queue.isEmpty()) {            depth ++;            ArrayList<Integer> layer = new ArrayList<Integer>();            int cur = 0, size = queue.size();            if ((depth & 1) == 0) { //如果是偶数层倒序添加                Iterator<TreeNode> it = queue.descendingIterator();                while (it.hasNext()) {                    layer.add(it.next().val);                }            }            else { //如果是奇数层正序添加                Iterator<TreeNode> it = queue.iterator();                while (it.hasNext()) {                    layer.add(it.next().val);                }            }            while (cur < size) {                TreeNode node = queue.poll();                if (node.left != null) {                    queue.offer(node.left);                }                if (node.right != null) {                    queue.offer(node.right);                }                cur ++;            }            layers.add(layer);        }        return layers;      }}

a. (depth & 1) == 0 是用来判断depth是否为偶数。

上述思想在实现上,还有另外一个版本

import java.util.ArrayList;import java.util.LinkedList;import java.util.Queue;public class Solution {    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {        ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();        if(pRoot == null){            return result;        }        boolean leftToRight = true;        Queue<TreeNode> layer = new LinkedList<TreeNode>();        ArrayList<Integer> layerList = new ArrayList<Integer>();        layer.add(pRoot);        int start = 0, end = 1;        while(!layer.isEmpty()){            TreeNode cur = layer.remove();            if(leftToRight){                //从左向右存储                layerList.add(cur.val);            }else{                //从右向左反向存储                layerList.add(0,cur.val);            }            start++;            if(cur.left!=null){                layer.add(cur.left);                       }            if(cur.right!=null){                layer.add(cur.right);            }            if(start == end){                end = layer.size();                start = 0;                              result.add(layerList);                leftToRight = !leftToRight;                layerList = new ArrayList<Integer>();            }        }        return result;    }}

【解题思路3】
//1.层序遍历,正常存储每一层的节点。
//2.奇数层正常打印,偶数层反转后再打印。
//3.此种方法reverse()的实现,复杂度较高。在测试用例数据量较大时,不适用。因此也不再给出具体实现。