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

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

 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.基于以上思想,可写出完整代码如下:

 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)。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值