【问题标题】:Is struct name a pointer?结构名称是指针吗?
【发布时间】:2013-08-31 22:54:51
【问题描述】:
typedef struct _Tree{
    int val;
    struct _Tree *left;
    struct _Tree *right;
}Tree;

Tree 是这里的指针吗?是否指向val的地址?

如果我定义Tree *node,这个怎么样? node是指向Tree地址的指针吗?

如果我们要插入val,我们应该使用insert(&node)还是insert(node)

void insert_Tree(Tree **root, int key){
if((*root) == NULL){
    (*root) = (Tree *)malloc(sizeof(Tree));
    (*root)->val = key;
    (*root)->left = NULL;
    (*root)->right = NULL;
    cout<<"insert data "<<key<<endl;
}else if(key< (*root)->val){
    insert_Tree(&(*root)->left, key);
    cout<<"go left"<<endl;
}else{
    insert_Tree(&(*root)->right, key);
    cout<<"go right"<<endl;
}
}
int main(){

Tree *root = NULL;
insert_Tree(&root, 10);
insert_Tree(&root, 20);
insert_Tree(&root, 5);
insert_Tree(&root, 100);
}

【问题讨论】:

  • 关于最后一个问题,如果你的insert()有可能修改传入指针的,那么你需要通过地址(即指针指向指针)。这对于传递可以修改的头/根指针的列表/树代码很常见。或者,您可以使用 insert() 函数 return 新的指针值,但我更喜欢前一个选项,因为我喜欢我的 API 来管理列表/树;不依赖 调用者 通过覆盖保存新的头/根。

标签: c struct tree binary-tree


【解决方案1】:

Tree 不是指针。它是用户定义类型struct _Tree别名。所以当你声明一个新变量时,而不是输入

struct _Tree foo;

你可以直接输入

Tree foo;

两者是等价的。

如果你声明

Tree *node;

C 中的一元 * 运算符是解引用/间接运算符,所以你说的是:*nodenode 的解引用值是 Tree。或者换句话说,node 是指向Tree 的指针,即指向struct _Tree 的指针。

在您为其分配内存之前,该指针未初始化:

node = malloc (sizeof (Tree));

在分配这块内存之前,指针一直指向某个未定义的地方。分配内存后,您可以将val 插入到节点中,如下所示:

node->val = val;

如何将这个node 本身插入二叉树是一个有趣的问题。你试过什么?

【讨论】:

  • 感谢详细,我粘贴代码。 1)树节点; 2)树*节点; 1)和2)是不同的,对吧?我认为 1) node 只是 Tree 的另一个名称 2) *node 是指向 Tree 结构的指针。我的理解对吗?谢谢
  • Tree node; 将声明一个Tree 类型的变量。 Tree *node 声明了一个指向 Tree 的指针。它们非常不同,就像int a;int *a;
  • 一般我们需要对树进行操作时推荐哪个,Tree *node还是Tree node?看了很多程序,Tree *node比较常见,你觉得呢?
  • Tree *node。如果根节点分配在堆栈上,而左右子节点分配在堆上,则插入新节点所涉及的递归变得更加棘手。
【解决方案2】:

不,Tree 根本不是指针或任何变量,它是struct _Tree 的别名typedef,可以与它互换使用。

如果您声明 Tree *node,则您声明了一个指向 Tree 结构的指针,但没有实际的结构本身。

如果没有更多代码,很难说您的 insert 函数是如何工作的。

【讨论】:

    【解决方案3】:

    这是定义这种简单结构的更常用方法:

    typedef struct{
        int val;
        Tree *left;
        Tree *right;
    }Tree;
    

    使用这种结构通常看起来像这样:

    Tree top;
    Tree left;
    Tree right;
    
    top.val = 0;
    top.left = &left;
    top.right = &right;        
    

    如您所见,Tree 在这里不是指针,而是类型结构定义。它就像一个类型,这意味着您可以使用 Tree 类型实例化一个变量。此外,您需要使用参考符号 (&) 来分配左右树指针,因为结构成员(左右)是指向 Tree 的指针。

    【讨论】:

    • 我贴上代码,连val都可以看到,模板使用&签名。
    【解决方案4】:

    Tree 是您自己的代码定义的数据类型。请注意您是如何在代码中调用它的,它与 intdouble 可能在同一个位置。

    既然是数据类型,那么也可以定义为指针:

      Tree *root;
    

    root 是指向结构/数据类型“树”的指针。 root 只有 4 个字节,并且 分配树结构。

    或者树可以是一组结构化/格式化的存储位置:

     Tree  node;
    

    node 是结构树,分配了实际的存储位置。如果您需要传递节点的地址,请指定:&amp;node,这将创建一个指向“节点”存储位置的指针。

    我认为您的其他问题取决于对 Tree 数据类型的理解。

    一般来说,当你开始编程时,你不需要定义双指针,比如Tree **root,所以重新检查你的代码并简化它。

    希望这会有所帮助。

    【讨论】:

    • 谢谢。如果我使用 Tree *root,它将是 root->val。如果我使用树根,它将是 root.val。什么时候用前者,什么时候用后者?
    • *root 是一个指向树结构的指针。指针对于构建链表、树等很有用。考虑到这一点时,不要混淆名称。如果你定义Tree *root;,你永远不会编码root.val。但您可以定义Tree node 和代码node.val
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 2020-12-09
    • 1970-01-01
    • 2021-12-03
    • 2017-11-10
    • 2012-04-22
    • 1970-01-01
    相关资源
    最近更新 更多