• 按之字形顺序打印二叉树


    按之字形顺序打印二叉树

    一、总结

    1、一行一行打印用的队列做BFS(广度优先搜索)

    2、这里因为要区分奇偶行,用了两个队列。

    3、效率的保障用的是奇数行存的时候是从左向右存入队列,偶数行的时候是从右向左存。而不是偶数行节点也会从左向右存入队列,然后array_reverse(),大量数据的时候这样效率很低的。

    二、题目描述

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

    三、代码

    代码一:java

     1 /**
     2  * 大家的实现很多都是将每层的数据存进ArrayList中,偶数层时进行reverse操作,
     3  * 在海量数据时,这样效率太低了。
     4  * (我有一次面试,算法考的就是之字形打印二叉树,用了reverse,
     5  * 直接被鄙视了,面试官说海量数据时效率根本就不行。)
     6  *
     7  * 下面的实现:不必将每层的数据存进ArrayList中,偶数层时进行reverse操作,直接按打印顺序存入
     8  * 思路:利用Java中的LinkedList的底层实现是双向链表的特点。
     9  *     1)可用做队列,实现树的层次遍历
    10  *     2)可双向遍历,奇数层时从前向后遍历,偶数层时从后向前遍历
    11  */
    12 public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
    13     ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
    14     if (pRoot == null) {
    15         return ret;
    16     }
    17     ArrayList<Integer> list = new ArrayList<>();
    18     LinkedList<TreeNode> queue = new LinkedList<>();
    19     queue.addLast(null);//层分隔符
    20     queue.addLast(pRoot);
    21     boolean leftToRight = true;
    22      
    23     while (queue.size() != 1) {
    24         TreeNode node = queue.removeFirst();
    25         if (node == null) {//到达层分隔符
    26             Iterator<TreeNode> iter = null;
    27             if (leftToRight) {
    28                 iter = queue.iterator();//从前往后遍历
    29             } else {
    30                 iter = queue.descendingIterator();//从后往前遍历
    31             }
    32             leftToRight = !leftToRight;
    33             while (iter.hasNext()) {
    34                 TreeNode temp = (TreeNode)iter.next();
    35                 list.add(temp.val);
    36             }
    37             ret.add(new ArrayList<Integer>(list));
    38             list.clear();
    39             queue.addLast(null);//添加层分隔符
    40             continue;//一定要continue
    41         }
    42         if (node.left != null) {
    43             queue.addLast(node.left);
    44         }
    45         if (node.right != null) {
    46             queue.addLast(node.right);
    47         }
    48     }
    49      
    50     return ret;
    51 }

    代码二:php

     1 <?php
     2  
     3 /*class TreeNode{
     4     var $val;
     5     var $left = NULL;
     6     var $right = NULL;
     7     function __construct($val){
     8         $this->val = $val;
     9     }
    10 }*/
    11 function MyPrint($pRoot)
    12 {
    13     if($pRoot == NULL)
    14         return [];
    15     $current = 0;  //记录当前行是奇数行还是偶数行
    16     $next    = 1;
    17      
    18     $stack[0] = array();
    19     $stack[1] = array();
    20     $resultQueue = array();
    21      
    22     array_push($stack[0], $pRoot);
    23      
    24     $i = 0; //记录达到数的第多少层
    25     $result = array();
    26     $result[0]= array();
    27      
    28     while(!empty($stack[0]) || !empty($stack[1])){
    29         $node = array_pop($stack[$current]);
    30         array_push($result[$i], $node->val);
    31          
    32         //var_dump($resultQueue);echo "</br>";
    33         if($current == 0){ //如果当前为奇数行,从左到右存入节点
    34             if($node->left != NULL)
    35                 array_push($stack[$next], $node->left);
    36             if($node->right != NULL)
    37                 array_push($stack[$next], $node->right);
    38         }else{ //当前为偶数行,从右向左存入节点
    39             if($node->right != NULL)
    40                 array_push($stack[$next], $node->right);
    41             if($node->left != NULL)
    42                 array_push($stack[$next], $node->left);
    43         }
    44          
    45         if(empty($stack[$current])){ //打印完一行之后
    46             $current = 1-$current;
    47             $next    = 1-$next;
    48             if(!empty($stack[0]) || !empty($stack[1])){
    49                 $i++;
    50                 $result[$i] = array();
    51             }
    52         }
    53          
    54     }
    55     return $result;
    56      
    57 }

    四、测试题-简答题

    1、php中类中的构造器的函数名是怎么写?

    解答:function __construct($val){}

    2、php中如何判断一个链表节点是否为空?

    解答:if($pRoot == NULL)

    3、php中如何返回一个空数组?

    解答:return [];

    4、之字形输出树的题目中,队列里面存节点还是值,答案数组里面存节点还是值?

    解答:队列里面存节点,答案数组里面存值。

    5、如何实现奇偶行切换?

    解答:$current = 0; //记录当前行是奇数行还是偶数行  $current = 1-$current;

    6、之字形输出树的题目中,如何判断树到达了下一层?

    解答:当前队列打印完之后。if(empty($stack[$current]))

    7、之字形输出树的题目中,答案数组继续加行的前提是什么?

    解答:奇数行队列或者偶数行队列至少有一个还有值。也就是非空。if(!empty($stack[0]) || !empty($stack[1]))

    8、php中如何判断一个数组非空?

    解答:用!empty()。if(!empty($stack[0]) || !empty($stack[1]))

    9、之字形输出树的题目中,要保证奇偶行操作方式不同,需要几个队列?

    解答:两个。

    10、之字形输出树的题目中,如何提高效率?

    解答:奇数行队列从左向右存,偶数行队列从右向左存。

    11、树的层次遍历,用的是什么数据结构?

    解答:队列。

    12、队列数据结构的操作核心是?

    解答:判断队列是否有值,有值的话就做入队或出队操作。

     
     
     
  • 相关阅读:
    梦想还需有,因它必实现——发现最新版iOS漏洞,OverSky团队专访
    细数iOS上的那些安全防护
    互联网业务安全之通用安全风险模型
    TaintDroid剖析之IPC级污点传播
    Android安全开发之通用签名风险
    Angular问题02 创建模块失败、 angular-cli名称问题、升级angular-cli
    Etyma01 ced ceed cess
    Angular19 自定义表单控件
    Angular18 RXJS
    Angular17 Angular自定义指令
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/9112654.html
Copyright © 2020-2023  润新知