考虑下面的结构重定向一个指针引用:在二叉搜索树
struct TElem {
int val;
};
typedef int TKey;
struct Node {
TKey key;
struct TElem *elem;
struct Node *left;
struct Node *right;
};
struct bst {
struct Node *root;
};
而且,这两个功能bst_Search
和bst_Insert
。
struct TElem* bst_Search(struct bst *T, TKey c, struct Node **posins)
{
struct Node *q = T->root;
posins = &(T->root); // (1)
while (q)
if (q->key == c)
return q->elem;
else if (c < q->key) {
q = q->left;
posins = &(q->left);
} else {
q = q->right;
posins = &(q->right);
}
return NULL;
}
void bst_Insert(struct bst *T, TKey c, struct TElem *x)
{
struct Node **posins;
struct TElem *v;
posins = malloc(sizeof *posins);
v = bst_Search(T, c, posins); // (2)
if (!v) {
struct Node *q = malloc(sizeof *q);
q->key = c;
q->elem = x;
q->left = NULL;
q->right = NULL;
*posins = q; // (3)
} else {
printf("Key exists %d\n", c);
}
free(posins);
}
而且main()
为“主”
struct bst *T = malloc(sizeof *T);
T->root = NULL;
struct TElem *x = elem_New(10);
bst_Insert(T, c, x);
我想插入一个新元素(elem_New
是工作的罚款)为BST,使用辅助功能bst_Search
返回一个指针到的地方插入。 (1)被称为第一个指向posins
到T->root
的内存地址。 (据我可以调试这是工作正常)。
posins
Then地址returns呼叫者function bst_Insert
,由于bst_Search
发现的地方,以便恢复在NULL
(2)。它正确地落在if
语句集合q
之内。然后在(3),我预计posins
指向哪里(在这种情况下,T> root根指向的地址)现在应该被重定向到新的树节点q
。相当于T->root = q
,但使用此调用作为参考。
当您搜索树来查找存储节点的位置时,您无法真正返回NULL并在该位置进行分配。记住左边或右边的指针有NULL,所以你不能返回它并给它分配一些东西,否则你会得到分段错误。一个简单的解决方案是返回父对象并在其右指针上分配,或者复制搜索逻辑并添加到正确的位置。 – Isac
@Isac'bst_Search'返回NULL,但不在我正在工作的返回值(存储在'v')中,我使用'posins'来代替。 – Lin
posins将从'posins =&(q-> right)'具有'NULL';'。请记住,当'q == NULL'这意味着在上一次迭代中'q-> left'和'q-> right'为'NULL'时,您退出。 – Isac