简体   繁体   English

使用指针将节点插入二叉树

[英]Inserting node into binary tree using pointers

I'm trying to create a method for inserting nodes into a BST with the following structs:我正在尝试创建一种使用以下结构将节点插入 BST 的方法:

// node structure
struct Node {
    int val;
    struct Node* left;
    struct Node* right;
};

// binary tree structure
struct BinaryTree {
    struct Node* root;
};

Originally I created this method for adding nodes to the tree:最初我创建了这个方法来向树添加节点:

// add value to binary tree
void _AddNode(struct Node* node, int val) {
    if (node == NULL)
        *(&node) = CreateNode(val);
    else if (val <= node->val)
        _AddNode(node->left, val);
    else
        _AddNode(node->right, val);
}
void AddNode(struct BinaryTree* tree, int val) {
    _AddNode(tree->root, val);
}

Using this function to construct the tree, I get a Segmentation fault: 11 error when I try to traverse, print, access data from the tree.使用此函数构建树时,当我尝试遍历、打印、访问树中的数据时,出现Segmentation fault: 11错误。

However, when I modified the function to pass in a double pointer and effectively do the same thing it worked:但是,当我修改函数以传入双指针并有效地执行相同的操作时:

// add value to binary tree
void _AddNode(struct Node** node, int val) {
    if (*node == NULL)
        *node = CreateNode(val);
    else if (val <= (*node)->val)
        _AddNode(&(*node)->left, val);
    else
        _AddNode(&(*node)->right, val);
}
void AddNode(struct BinaryTree* tree, int val) {
    _AddNode(&tree->root, val);
}

Why does the latter work, but the former doesn't.为什么后者有效,而前者无效。

However, when I modified the function to pass in a double pointer and effectively do the same thing it worked但是,当我修改函数以传入双指针并有效地执行相同的操作时

Substantially the same thing, on fundamentally different data .在根本不同的数据上,本质上是相同的。 The (&node) in your original attempt gives you a pointer to a local variable .您最初尝试中的(&node)为您提供了一个指向局部变量的指针。 When you dereference that and assign to the result, you are therefore modifying the local variable.当您取消引用它并分配给结果时,您正在修改局部变量。 Such a modification is not visible in any way to the caller.这种修改对调用者来说是不可见的。

On the other hand if you pass (say) a suitable double pointer to your function, say _AddNode(&(*node)->left, 42) , then the value of the function parameter points to the same thing: the (*node)->left of the caller.另一方面,如果你传递(比如)一个合适的双指针到你的函数,比如_AddNode(&(*node)->left, 42) ,那么函数参数的值指向同样的东西: (*node)->left呼叫者的(*node)->left If you dereference that pointer and assign to the result then naturally that is visible to the caller.如果您取消引用该指针并分配给结果,那么调用者自然可以看到它。

It seems that both the original and modified function are identical看来原来和修改后的功能都是一样的

Clearly, they are not lexically identical.显然,它们在词汇上并不相同。 You seem to mean that they appear to you to be equivalent , but since the difference in behavior disproves such an equivalence, it stands to reason that the manifest differences in the two functions in fact produce different semantics.您似乎是说它们在您看来是等价的,但是由于行为上的差异证明了这种等价性,因此这两个函数的明显差异实际上会产生不同的语义是合情合理的。 The key thing that seems to have confused you is that in C, function arguments are always passed by value , so each function parameter starts with the value passed by the caller, but is not an alias for the caller's corresponding argument.似乎让您感到困惑的关键是,在 C 中,函数参数始终按值传递,因此每个函数参数都以调用者传递的开头,但不是调用者相应参数的别名。 Parameters of pointer type are no exception.指针类型的参数也不例外。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM