刷题笔记:力扣第144题-二叉树的前序遍历

1.本题考查二叉树的前序遍历,前序遍历的意思为一开始就遍历读取根节点的值,遍历顺序为"根-左-右"。本题先使用递归算法,返回值为void,因为每个节点的值会被存放到已经开辟的结果数组空间中,每次只需要传入当前节点的指针以及结果数组即可。完整代码如下:

cpp 复制代码
 1. /**
 2.  * Definition for a binary tree node.
 3.  * struct TreeNode {
 4.  *     int val;
 5.  *     struct TreeNode *left;
 6.  *     struct TreeNode *right;
 7.  * };
 8.  */
 9. /**
10.  * Note: The returned array must be malloced, assume caller calls free().
11.  */
12. // 全局变量,记录结果数组当前存放元素的下标
13. int cur;
14. // 递归回溯函数,二叉树前序遍历:根 -> 左 -> 右
15. void backTrack(struct TreeNode* node, int* res){
16.     // 递归终止条件:当前节点为空直接返回
17.     if (node == NULL) return;
18.     // 访问根节点,存入结果数组
19.     res[cur++] = node->val;
20.     // 递归遍历左子树
21.     backTrack(node->left, res);
22.     // 递归遍历右子树
23.     backTrack(node->right, res);
24. }
25. // 二叉树前序遍历入口函数
26. int* preorderTraversal(struct TreeNode* root, int* returnSize) {
27.     // 分配结果数组空间,固定大小101
28.     int* res = (int*)malloc(sizeof(int) * 101);
29.     // 初始化下标计数器
30.     cur = 0;
31.     // 启动递归遍历
32.     backTrack(root, res);
33.     // 设置返回数组长度
34.     *returnSize = cur;
35.     return res;
36. }

该算法时间复杂度和空间复杂度均为O(n)。

2.本题的进阶方法是使用迭代法。递归法本质上是依靠栈来实现,现在要用迭代法来模拟递归也要使用栈。核心逻辑为循环判断栈是否为空,不为空就将当前栈顶元素弹出栈。之后判断栈顶元素的左右子节点是否为空,若不为空就先弹入右节点、再弹入左节点,原因是栈遵循"先进后出",前序遍历时需要先遍历左节点再遍历右节点,所以让右节点先进去。需要注意的是,要考虑root节点为空的特殊情况,此时就需要直接返回。

3.基于以上思想,可写出完整代码如下:

cpp 复制代码
 1. /**
 2.  * Definition for a binary tree node.
 3.  * struct TreeNode {
 4.  *     int val;
 5.  *     struct TreeNode *left;
 6.  *     struct TreeNode *right;
 7.  * };
 8.  */
 9. /**
10.  * Note: The returned array must be malloced, assume caller calls free().
11.  */
12. // 二叉树前序遍历,迭代法(栈实现),顺序:根 -> 左 -> 右
13. int* preorderTraversal(struct TreeNode* root, int* returnSize) {
14.     // 分配结果数组,固定容量101
15.     int* res = (int*)malloc(sizeof(int) * 101);
16.     // cnt记录结果数组有效元素个数
17.     int cnt = 0;
18.     // 栈数组,存放树节点指针
19.     struct TreeNode* stack[101];
20.     // top为栈的下一个可写入位置
21.     int top = 0;
22.     // 根节点为空,直接返回空结果
23.     if (root == NULL) {
24.         *returnSize = 0;
25.         return res;
26.     }
27.     // 根节点先入栈
28.     stack[top++] = root;
29.     
30.     // 栈不为空就循环处理
31.     while (top != 0){
32.         // 弹出栈顶节点
33.         struct TreeNode* cur = stack[--top];
34.         // 访问当前节点,存入结果数组
35.         res[cnt++] = cur->val;
36.         // 先压右孩子(栈后进先出,右先入栈保证左先出栈)
37.         if (cur->right) stack[top++] = cur->right;
38.         // 再压左孩子
39.         if (cur->left) stack[top++] = cur->left;
40.     }
41.     // 设置返回数组有效长度
42.     *returnSize = cnt;
43.     return res;
44. }

该算法时间复杂度和空间复杂度均为O(n)。

相关推荐
微尘hjx5 小时前
【ByteTrack 04】多轨迹算法ByteTrack改进点
算法·yolo·目标检测·目标跟踪·bytetrack·ultralytics·车跟踪
摇滚侠5 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
silvamux_7 小时前
10款模型写种草笔记:可发布性、返工来源与成本数据缺口复盘
java·数据库·笔记
蒸蒸yyyyzwd8 小时前
kafka、redis、mysql不熟悉问题总结
笔记·八股
hgy89698 小时前
深度学习(小白笔记)——迁徙
人工智能·笔记·深度学习
摇滚侠8 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 11
java·笔记·python
小蒋观天下9 小时前
雷击与浪涌防护:前端SPD选型、接地网误区,接地不当反而引入干扰
深度学习·算法·机器学习
WBluuue10 小时前
数据结构与算法:分块(一):块状数组、块状链表
数据结构·c++·算法·链表
圣保罗的大教堂10 小时前
leetcode 3619. 总价值可以被 K 整除的岛屿数目 中等
leetcode