

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