[英]binary tree recursive insertion with pointer to pointer
void insert(node ** tree, int val)
{
node *temp = NULL;
if(!(*tree))
{
temp = (node *)malloc(sizeof(node));
temp->left = temp->right = NULL;
temp->data = val;
*tree = temp;
return;
}
if(val < (*tree)->data)
{
insert(&(*tree)->left, val);
}
else if(val > (*tree)->data)
{
insert(&(*tree)->right, val);
}
}
此函數使用指向指針node ** tree
指針來表示二叉樹的頭。 我在許多教程和網站上都遇到了相同的方法。 我想知道為什么每個人都堅持使用指針指向指針,為什么不只是使用“ node * tree”。 我認為即使指向樹頭的指針也能很好地完成工作,而僅使用指向樹頭的指針,遞歸調用將如下所示(如果我錯了,請糾正我):
insert(tree->left, val); // assuming definisiton as void insert(node *tree, int val);
要么
insert(tree->right, val); // assuming definisiton as void insert(node *tree, int val);
如果我的理解是錯誤的,請糾正我。 我是新手。 謝謝。
請記住,在C中,參數是通過value傳遞的 ,這意味着將作為參數傳遞的表達式的值復制到函數中。 因此,如果您在函數內更改參數,則僅更改副本,並且該更改將對調用者不可見(即更改丟失)。
為了克服該問題,您可以通過傳遞指針來模擬按引用傳遞。 如果要更改指針,則必須將指針傳遞給該指針。
如果查看insert
函數,您會發現當*tree
為NULL
(即沒有節點)時,它會分配給指針。 如果您沒有將指針傳遞給指向節點的指針,那將不起作用。
愚蠢的例子:
#include <stdio.h>
void func1(const char *s)
{
s = "hello from func1";
}
void func2(const char **s)
{
*s = "hello from func2";
}
int main(void)
{
const char *s1 = "foo";
const char *s2 = "bar";
func1(s1); /* Passing pointer by value */
func2(&s2); /* Passing pointer by "reference" */
printf("s1 = \"%s\"\n", s1);
printf("s2 = \"%s\"\n", s2);
}
上面的小示例程序將打印
s1 = "foo" s2 = "hello from func2"
這是因為tree
可以為空( NULL
)。 在這種情況下,您可以設置外部指針使其指向新的根。
node *root = NULL;
insert(root, 10);
傳遞給函數的兩種類型:
1.按值傳遞=創建值的副本。 函數終止后,對該值的任何更改都將丟失。
2.通過引用傳遞=不會創建副本,但指向要傳遞的值。 如果發生更改,則值將更改。
雙指針(**)指向單個指針(*)的地址。 因此,如果將單指針傳遞給函數,則需要使用雙指針來更改單指針的值(地址)。 否則,沒有任何變化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.