考慮下面的結構重定向一個指針引用:在二叉搜索樹
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