赞
踩
先发二叉树的前、中、后序遍历的三个题目,归纳的方法在下面。
给你二叉树的根节点 root
,返回它节点值的 前序 遍历。
示例 1:
输入:root = [1,null,2,3] 输出:[1,2,3]
示例 2:
输入:root = [] 输出:[]
示例 3:
输入:root = [1] 输出:[1]
示例 4:
输入:root = [1,2] 输出:[1,2]
示例 5:
输入:root = [1,null,2] 输出:[1,2]
提示:
[0, 100]
内-100 <= Node.val <= 100
给定一个二叉树的根节点 root
,返回 它的 中序 遍历 。
示例 1:
输入:root = [1,null,2,3] 输出:[1,3,2]
给你一棵二叉树的根节点 root
,返回其节点值的 后序遍历 。
示例 1:
输入:root = [1,null,2,3] 输出:[3,2,1]
二叉树的前序遍历是中左右,在递归的处理逻辑中就是先处理输入的节点,再递归该节点的左节点和右节点。因为该题是返回存放遍历的值的数组,所以需设置一个全局数组用以存放二叉树的值。
递归参数是二叉树的节点,单层递归逻辑是先将传入的二叉树节点的值放入数组,再递归左右节点,终止条件是传入的节点为null。
- class Solution {
- private $result = [];
-
- /**
- * @param TreeNode $root
- * @return Integer[]
- */
- function preorderTraversal($root) {
- if($root == null)
- return [];
- $this->result[] = $root->val;
- $this->preorderTraversal($root->left);
- $this->preorderTraversal($root->right);
- return $this->result;
- }
- }
同上逻辑类似,只是递归左右节点和处理中节点的顺序不同。
- class Solution {
- private $result = [];
- /**
- * @param TreeNode $root
- * @return Integer[]
- */
- function postorderTraversal($root) {
- if(!$root) {
- return [];
- }
- $this->postorderTraversal($root->left);
- $this->postorderTraversal($root->right);
- $this->result[] = $root->val;
- return $this->result;
- }
- }
- class Solution {
- private $result = [];
- /**
- * @param TreeNode $root
- * @return Integer[]
- */
- function inorderTraversal($root) {
- if($root == null)
- return [];
- $this->inorderTraversal($root->left);
- $this->result[] = $root->val;
- $this->inorderTraversal($root->right);
- return $this->result;
- }
- }
这里的迭代遍历是使用栈来进行遍历,先将root节点放入栈中,再将root节点取出放入数组,将该root节点的右左节点放入栈中,因为是前序遍历:中左右,故放入的时候是按照右、左的顺序。然后再不断重复此过程,每从栈中取出一个节点,如果该节点的右左节点存在,都要把该节点的右左节点放入。
这里是利用了前序遍历的特性,因为是中左右的顺序,每次在把中节点的值放入数组时,就可以顺便通过中节点来获取其左右节点了。后序遍历(左右中)也可以用与这个类似的方法。
但是中序遍历就不可以,因为中序遍历中节点是在中间的,不好处理,无法判断哪个是中节点。
- class Solution {
- /**
- * @param TreeNode $root
- * @return Integer[]
- */
- function preorderTraversal($root) {
- $stack = new splStack();
- $result = [];
- $stack->push($root);
-
- while(!$stack->isEmpty()) {
- $cur = $stack->pop();
- $result[] = $cur->val;
- if($cur->right) {
- $stack->push($cur->right);
- }
- if($cur->left) {
- $stack->push($cur->left);
- }
- }
-
- return $result;
- }
- }
- 控制台
后序遍历的逻辑和上面前序的类似,前序是按中右左的顺序进行的,后序就要按中左右的顺序进行,最后得到的数组就是按中右左的顺序遍历的,把数组反转一下就得到了左右中也就是后序遍历了。
- class Solution {
- /**
- * @param TreeNode $root
- * @return Integer[]
- */
- function postorderTraversal($root) {
- $stack = new splStack();
- $result = [];
- $stack->push($root);
-
- while(!$stack->isEmpty()) {
- $cur = $stack->pop();
- $result[] = $cur->val;
- if($cur->left) {
- $stack->push($cur->left);
- }
- if($cur->right) {
- $stack->push($cur->right);
- }
- }
- //反转数组
- $result = array_reverse($result);
- return $result;
- }
- }
- 控制台
上面已经说过了中序不能用以上的方法。中序遍历:左中右 要从左边开始遍历起,但题目又是从根节点起步,所以需要一个指针,一层层到达最左的节点,从这个节点开始处理。
但此时指针在最底层,又如何把指针重新指向父节点呢?那么就需要在指针遍历到最左这个节点的过程中,把遍历到的节点全都入栈。在指针终于遍历到最左的节点时,把该节点出栈、放入数组,如果该节点的右节点存在,就按相同的逻辑遍历它的右节点;如果右节点也不在,就要回溯到该节点的父节点进行遍历,此时栈的顶端元素正是该节点的父节点,所以将父节点出栈处理,再重复遍历右节点、遍历父节点的过程。
里面的单层处理过程正是左中右的顺序:
第一层:遍历到最左(此时左节点为空),处理这个最左节点(相当于处理中节点),处理该节点的右节点。
第二层:处理完最左节点的右节点后,指针回溯指向的最左节点的父节点也是一个中节点(此时左节点相当于这个节点的左子树,已经在上一层中遍历处理过了),再处理该节点的右节点。
- class Solution {
- /**
- * @param TreeNode $root
- * @return Integer[]
- */
- function inorderTraversal($root) {
- $stack = new splStack();
- $result = [];
- $cur = $root;
-
- while(!$stack->isEmpty() || $cur) {
- if($cur) {
- $stack->push($cur);
- $cur = $cur->left;
- } else {
- $cur = $stack->pop();
- $result[] = $cur->val;
- $cur = $cur->right;
- }
- }
- return $result;
- }
- }
上面的迭代遍历的方法,只适用于前后序遍历,而这个统一遍历方法是前中后序都适用的。依旧是使用栈来存放节点。每个节点会入栈两次,第一次用于获取该节点的左右节点,第二次用于将该节点的值存入数组。节点第二次入栈后,会将一个null入栈,将null放在该节点后面,用于标识。
前中后序的区别在于,第一次把节点出栈时、再把该节点和其左右节点入栈的顺序。如果是前序遍历,就把中左右反着来,按右左中的顺序入栈(这里的中节点是第二次入栈,所以还需加一个null),其他同理。
- class Solution {
- /**
- * @param TreeNode $root
- * @return Integer[]
- */
- function preorderTraversal($root) {
- $stack = new splStack();
- $result = [];
- if($root) {
- $stack->push($root);
- }
-
- while(!$stack->isEmpty()) {
- $cur = $stack->top();
-
- if($cur != null) {
- $stack->pop();
-
- if($cur->right) $stack->push($cur->right);
-
- if($cur->left) $stack->push($cur->left);
-
- $stack->push($cur);
- $stack->push(null);
- } else {
- $stack->pop();
- $temp = $stack->pop();
- $result[] = $temp->val;
- }
-
- }
-
-
- return $result;
- }
- }
与上面的前序遍历类似,只是换了下位置
- class Solution {
- /**
- * @param TreeNode $root
- * @return Integer[]
- */
- function postorderTraversal($root) {
- $stack = new splStack();
- $result = [];
- if($root) $stack->push($root);
-
- while(!$stack->isEmpty()) {
- $cur = $stack->top();
- if($cur != null) {
- $stack->push(null);
-
- if($cur->right) $stack->push($cur->right);
-
- if($cur->left) $stack->push($cur->left);
- } else {
- $stack->pop();
- $temp = $stack->pop();
- $result[] = $temp->val;
- }
- }
-
- return $result;
- }
- }
同上
- class Solution {
- /**
- * @param TreeNode $root
- * @return Integer[]
- */
- function inorderTraversal($root) {
- $stack = new splStack();
- $result = [];
- if($root) {
- $stack->push($root);
- }
-
- while(!$stack->isEmpty()) {
- $cur = $stack->top();
- if($cur != null) {
- $stack->pop();
- if($cur->right) $stack->push($cur->right);
-
- $stack->push($cur);
- $stack->push(null);
-
- if($cur->left) $stack->push($cur->left);
- } else {
- $stack->pop();
- $temp = $stack->pop();
- $result[] = $temp->val;
- }
- }
- return $result;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。