二叉树创建传二级指针和不传二级指针的实现方法和一些问题

文章讨论了三种创建二叉树的C语言函数:A、B和C。函数A使用二级指针实现前序遍历创建,能直接修改外部变量;函数B通过返回新节点创建树,只用一级指针;函数C存在疑问,其行为与B类似但未返回结果。关键在于如何在函数内部修改外部指针,需理解指针、解引用及内存管理。
摘要由CSDN通过智能技术生成

struct TreeNode
{
    char data;
    struct TreeNode *left, *right;
};
//依照前序遍历创建一颗二叉树
void A(struct TreeNode **root)
{
    char c;
    scanf("%c", &c);
    if (c==' '){
    *root = NULL;
}
else
{
    *root = malloc(sizeof(struct TreeNode));
    (*root)->data = c;
    A(&(*root)->left);
    A(&(*root)->right);
}


struct TreeNode *B(struct TreeNode *root)
{
    char c;

    scanf("%c", &c);
    if (c==' ')
    root = NULL;
}
    else
        {
    root = malloc(sizeof(struct TreeNode));
    root->data = c;
    root->left = B(root->left);
    root->right = B(root->right);
        }
 return root;
}


//函数C是错误的吗?
void C(struct TreeNode *root)
{
    char c;
    scanf("%c", &c);
    if (c==' ')
    {
        root = NULL;
    }
    else
    {
        root = malloc(sizeof(struct TreeNode));    
        root->data = c;
        C(root->left);
        C(root->right);
    }
}

1.上面是创建二叉树的三个函数,函数A和函数B的区别在哪?
2.为什么函数A非要用到二级指针而函数B却只需要一级指针?
3.函数C是错误的吗?为什么函数B可以用一级指针是对的呢?

1 区别就是A不用返回值,也能修改函数外的root指针,而B是在函数设置指针指向并返回函数内的指针
2 因为A要直接修改函数外的root指针,而B不是修改函数外的指针,而是返回一个新指针。这个问题回答过很多次了。
形参只是实参的拷贝,形参本身的内存地址和实参的内存地址不同(在不同的函数栈里),所以在函数内修改形参的内存,不能影响函数外的实参。
什么叫修改形参的内存?直接对形参(变量)赋值就是修改形参(变量)的内存,比如 int a=5;//a的内存信息为5, a=10;//赋值语句修改了a的内存信息为10
所以B的 root = malloc(sizeof(struct TreeNode)); 就是修改形参的内存,这个root和函数外的实参的内存空间不同,所以修改它并不会对实参的内存造成影响,所以必须把它做为返回值返回去,否则函数外就没法获得这个变化的值。(也就是通过返回值来把变化返回去,让函数外也能获得这个变化)
A为什么可以影响函数外的实参?因为A传进来的是实参的地址,而不是实参的值,且函数内没有修改形参的内存(也就是没用直接对形参用赋值语句),而是对形参解引用(也就是找到实参的地址)去赋值。什么叫解引用赋值?*xx=yy就是解引用赋值,即A是用*root = malloc(sizeof(struct TreeNode));来赋值的,*root就是函数外的实参(因为root是实参的地址,*root就是实参),所以A能改变函数外的指针指向新的地址。
要记住,要想在函数内修改函数外的变量,必须满足三个条件
一,形参必须用指针
二,必须是把实参的地址传给形参
三,函数内必须是对形参解引用赋值而不能直接对形参赋值

 

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值