144.binary-tree-preorder-traversal.md 3.4 KB
Newer Older
Y
yulecc 已提交
1
## 题目地址(144. 二叉树的前序遍历)
L
luzhipeng 已提交
2

Y
yulecc 已提交
3
https://leetcode-cn.com/problems/binary-tree-preorder-traversal/
4 5 6 7

## 题目描述

```
Y
yulecc 已提交
8
给定一个二叉树,返回它的 前序 遍历。
9

Y
yulecc 已提交
10
 示例:
11

L
lucifer 已提交
12
输入: [1,null,2,3]
13 14 15 16
   1
    \
     2
    /
L
lucifer 已提交
17
   3
18

Y
yulecc 已提交
19 20
输出: [1,2,3]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
21 22 23

```

L
lspeer 已提交
24 25 26 27 28
## 前置知识

- 递归
-

29 30 31 32 33 34 35
## 公司

- 阿里
- 腾讯
- 百度
- 字节

36 37 38 39 40 41 42
## 思路

这道题目是前序遍历,这个和之前的`leetcode 94 号问题 - 中序遍历`完全不一回事。

前序遍历是`根左右`的顺序,注意是`根`开始,那么就很简单。直接先将根节点入栈,然后
看有没有右节点,有则入栈,再看有没有左节点,有则入栈。 然后出栈一个元素,重复即可。

43
> 其他树的非递归遍历可没这么简单
44

L
lucifer 已提交
45
![](https://tva1.sinaimg.cn/large/007S8ZIlly1ghltxumvwfj30zu0nttak.jpg)
46 47 48

(迭代 VS 递归)

49 50 51
## 关键点解析

- 二叉树的基本操作(遍历)
L
luzhipeng 已提交
52
  > 不同的遍历算法差异还是蛮大的
53 54 55 56 57 58
- 如果非递归的话利用栈来简化操作

- 如果数据规模不大的话,建议使用递归

- 递归的问题需要注意两点,一个是终止条件,一个如何缩小规模

L
luzhipeng 已提交
59
1. 终止条件,自然是当前这个元素是 null(链表也是一样)
60 61

2. 由于二叉树本身就是一个递归结构, 每次处理一个子树其实就是缩小了规模,
L
luzhipeng 已提交
62 63
   难点在于如何合并结果,这里的合并结果其实就是`mid.concat(left).concat(right)`,
   mid 是一个具体的节点,left 和 right`递归求出即可`
64 65 66

## 代码

L
luzhipeng 已提交
67
- 语言支持:JS,C++
68 69 70

JavaScript Code:

71 72 73 74 75
```js
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
L
lucifer 已提交
76
var preorderTraversal = function (root) {
L
luzhipeng 已提交
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
  // 1. Recursive solution

  // if (!root) return [];

  // return [root.val].concat(preorderTraversal(root.left)).concat(preorderTraversal(root.right));

  // 2. iterative solutuon

  if (!root) return [];
  const ret = [];
  const stack = [root];
  let t = stack.pop();

  while (t) {
    if (t.right) {
      stack.push(t.right);
    }
    if (t.left) {
      stack.push(t.left);
96
    }
97
    ret.push(t.val);
L
luzhipeng 已提交
98 99
    t = stack.pop();
  }
100

L
luzhipeng 已提交
101
  return ret;
102 103
};
```
L
luzhipeng 已提交
104

105
C++ Code:
L
luzhipeng 已提交
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 134
```C++
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> v;
        vector<TreeNode*> s;
        while (root != NULL || !s.empty()) {
            while (root != NULL) {
                v.push_back(root->val);
                s.push_back(root);
                root = root->left;
            }
            root = s.back()->right;
            s.pop_back();
        }
        return v;
    }
};
```
L
lucifer 已提交
135

L
lucifer 已提交
136 137
**复杂度分析**

L
lucifer 已提交
138 139
- 时间复杂度:$O(N)$
- 空间复杂度:$O(N)$
140 141 142 143

## 相关专题

- [二叉树的遍历](https://github.com/azl397985856/leetcode/blob/master/thinkings/binary-tree-traversal.md)
L
lucifer 已提交
144 145 146 147

大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。
大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg)