树OJ题 (5)---二叉树的前序遍历&& (6)---二叉树遍历

题目一

题目描述

思路

1.先解释一下函数第二个参数的意思,因为二叉树是逻辑结构,存储结构是数组,leetcode题目设计的就是不知道数组的大小,因此函数外部会传入一个变量,函数形参用returnSize指针来接收该变量地址,目的就是为了能够改变外部的数组大小的变量~

2. 数组空间是malloc出来的,但是我们并不知道要开多大空间,因此自己定义了求节点个数的函数

int TreeSize(struct TreeNode* root)
{
    return root == NULL? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

第一次提交时代码

int TreeSize(struct TreeNode* root)
{
    return root == NULL? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

void _preorder(struct TreeNode* root, int* a, int i)
{
    if(root == NULL)
       return;
    a[i++] = root->val;
    _preorder(root->left, a, i);
    _preorder(root->right, a, i);
}

int* preorderTraversal(struct TreeNode* root, int* returnSize){
    *returnSize = TreeSize(root);
    int* a = (int*)malloc(*returnSize *sizeof(int));
    int i = 0;
    _preorder(root, a, i);
    return a;
}

 分析错误原因:

解决方案:传i的地址&i,用*pi来接收i的地址,这样的话每一个栈帧虽然都有一个pi,但是这些pi都指向了i,直接(*pi)++即可

正确代码

int TreeSize(struct TreeNode* root)
{
    return root == NULL? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

void _preorder(struct TreeNode* root, int* a, int* pi)
{
    if(root == NULL)
       return;
    a[(*pi)++] = root->val;
    _preorder(root->left, a, pi);
    _preorder(root->right, a, pi);
}

int* preorderTraversal(struct TreeNode* root, int* returnSize){
    *returnSize = TreeSize(root);
    int* a = (int*)malloc(*returnSize *sizeof(int));
    int i = 0;
    _preorder(root, a, &i);
    return a;
}

 ps:想使用全局变量也是可以的,但是要注意leetcode的特点,他会多次调用你写的函数,所以下面这种写法就是有问题的~

 

 可以看到出了内存错误,而且是第二个测试用例没过,就是因为第二次调用函数时i还是保留了上一次的值,导致a[i++] = root->val 下标越界~

所以记得把i初始化成0

正确代码

int i = 0;
int TreeSize(struct TreeNode* root)
{
    return root == NULL? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

void _preorder(struct TreeNode* root, int* a)
{
    if(root == NULL)
       return;
    a[i++] = root->val;
    _preorder(root->left, a);
    _preorder(root->right, a);
}

int* preorderTraversal(struct TreeNode* root, int* returnSize){
    *returnSize = TreeSize(root);
    int* a = (int*)malloc(*returnSize *sizeof(int));
    i = 0;
    _preorder(root, a);
    return a;
}

 还是不推荐使用全局变量哦~

题目二

题目描述

这道题遍历比较特殊,因为题中给的是二叉树前序遍历的结果,要求实现中序遍历,因此我们需要先根据前序遍历结果构建出二叉树,然后进行中序遍历

根据前序构建二叉树

技巧:NULL是结束的标志,是构建根结束的标志,是构建左子树结束的标志,同样也是构建右子树结束的标志~

把握住前序的关键:每棵树的遍历顺序都要是根-左子树-右子树

 代码实现

#include <stdio.h>
#include <stdlib.h>
typedef char BTDataType;
typedef struct BinaryTreeNode
{
    BTDataType data;
    struct BinaryTreeNode* left;
    struct BinaryTreeNode* right;
}BTNode;

BTNode* BuyNode(BTDataType x)
{
    BTNode* node = (BTNode*)malloc(sizeof(BTNode));
    if(node == NULL)
    {
        perror("malloc fail\n");
        return NULL;
    }
    node->data = x;
    node->left = NULL;
    node->right = NULL;

    return node;
}
BTNode* CreateTree(char* a, int* pi)
{
    if(a[*pi] == '#')
    {
        (*pi)++;
        return NULL;
    }
    BTNode* root = BuyNode(a[*pi]);
    (*pi)++;

    root->left = CreateTree(a,pi);
    root->right = CreateTree(a,pi);
    return root;
}
void InOrder(BTNode* root)
{
    if(root == NULL)
      return;
    InOrder(root->left);
    printf("%c ",root->data);
    InOrder(root->right);
}
int main() {
    char a[100];
    scanf("%s",a);
    int i = 0;
    BTNode* root = CreateTree(a, &i);
    InOrder(root);
    printf("\n");
}

代码中同样用到了pi指针,通过上一道题大家应该已经明白了为什么要传i地址了~

 本篇文章就分享到这了,欢迎大家交流指正~

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值