144. 二叉树的前序遍历(指针用法整理,bug很多)

114 阅读3分钟

(为应付面试,本题开始从二叉树开始练习,并采用ACM输入输出模式)

144. 二叉树的前序遍历

简单

相关标签

premium lock icon相关企业

给你二叉树的根节点 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型)去遍历去赋值。终于成功了。