(为应付面试,本题开始从二叉树开始练习,并采用ACM输入输出模式)
简单
相关标签
相关企业
给你二叉树的根节点 root ,返回它节点值的 前序 **遍历。
示例 1:
输入: root = [1,null,2,3]
输出: [1,2,3]
解释:
示例 2:
输入: root = [1,2,3,4,5,null,8,null,null,6,7,9]
输出: [1,2,4,5,6,7,3,8,9]
解释:
示例 3:
输入: root = []
输出: []
示例 4:
输入: root = [1]
输出: [1]
提示:
- 树中节点数目在范围
[0, 100]内 -100 <= Node.val <= 100
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
题解: 第一次做,先用leetcode的核心代码模式,下次再用acm输入输出模式。 开头预处理if(root == NULL); 访问左右孩子之前也要if(root->left != NULL) preorder(root->left......)
void preorder (struct TreeNode* root, int* returnSize, int* ans){
if (root == NULL)
return;
ans[*returnSize] = root->val;
(*returnSize) ++;
if (root->left != NULL)
{
preorder(root->left, returnSize, ans);
}
if (root->right != NULL)
{
preorder(root->right, returnSize, ans);
}
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
int* ans = (int*)malloc(sizeof(int) * 100);
*returnSize = 0;
preorder (root, returnSize, ans);
return ans;
}
第一次bug: solution.c: In function ‘preorderTraversal’ Line 18: Char 9: error: too few arguments to function ‘preorderTraversal’ [solution.c] 18 | preorderTraversal(root->left); 即函数传入参数不足,因为平时伪代码递归调用只传入左右孩子节点,这有个returnSize不会处理,所以没传。 (这里发现对指针符号的理解不到位:&表示取地址符,&a是变量a存放的地址值;* 是访问该指针所指的地方。如果p是一个指针,* p就是访问p所指的地址值上存放的值。)
第二次bug: solution.c: In function ‘preorderTraversal’ Line 15: Char 19: error: invalid type argument of unary ‘*’ (have ‘int’) [solution.c] 15 | printf ("%d", * root->val); 错误原因是, 访问结构体成员时,root是指向结构体的指针,我使用了root->val,实际上root是指向节点的指针,root->val就是访问结构体的成员 而如果是NodeA是结构体本身的名称,那么访问其成员应该用NodeA.val,应用点而不是->。
第三次bug: 没有给函数写返回值,题目要求返回前序遍历序列,观察发现返回值是int*,所以应该建立一维数组保存遍历序列,返回首地址。但是数组大小难以在过程中一个一个的增大,要一开始就给定,所以看下答案如何处理returnSize这个传入参数。看答案发现题目说过,树的节点数不超过100,所以直接开100大的数组。
第四次bug: *returnSize ++会先取returnSize的值然后自增,而不是取returnSize指的值再自增,正确应该写(*returnSize) ++; 第二是创建100大的数组放在了函数内部,每次递归调用都会创建一次数组,因此应该在外面单独创建。可是leetcode已经定死函数不能往里面传入ans数组,所以我只能重新写一个函数来递归,这个函数就用来建数组吧。分为两个函数,力扣给的用来建数组,然后参数都传入自己写的那个函数(void型)去遍历去赋值。终于成功了。