You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中void函数修改BST指针失效问题求助

BST查找函数中指针修改无法保留的问题

我尝试实现一个二叉搜索树(BST)的查找函数,功能是查找指定int类型的key,找到后将found指针指向该节点,同时找到该节点的前驱(pre)和后继(suc)并赋值给对应指针。

实现的函数代码

void findPreSuc(struct node *root, struct node* found, struct node* pre, struct node* suc, int key)
{
    // Base case
    if (root == NULL){  
        return ;
    }
    // If key is present at root
    if (root->data == key)
    {
        found=root;
        printf("\n%d",found->data); //test if root node gets passed to found
        // the maximum value in left subtree is predecessor
        if (root->left_child != NULL)
        {
            struct node* tmp = root->left_child;
            while (tmp->right_child){
                tmp = tmp->right_child;
                pre = tmp ;
            }
        }
 
        // the minimum value in right subtree is successor
        if (root->right_child != NULL)
        {
            struct node* tmp = root->right_child;
            while (tmp->left_child){
                tmp = tmp->left_child;
                suc = tmp ;
            }
        }
        return ;
    }
 
    // If key is smaller than root's key, go to left subtree
    if (root->data > key)
    {
        suc = root ;
        findPreSuc(root->left_child, found, pre, suc, key) ;
    }
    else // go to right subtree
    {
        pre = root ;
        findPreSuc(root->right_child, found, pre, suc, key) ;
    }
}

测试的main函数代码

int main()
{
    struct node *root=NULL;
    struct node *suc=NULL;
    struct node* pre=NULL;  
    struct node* found=NULL;
    root = insert(root, 50);
    insert(root, 30);
    insert(root, 20);
    insert(root, 40);
    insert(root, 70);
    insert(root, 60);
    insert(root, 80);
    findPreSuc(root, found, pre, suc, 60);
    if (found==NULL)
    {
        printf("\ndidnt work");
    }    
    return 0;
}

运行输出

60
didnt work

可以看到函数执行时确实修改了内部的found指针(打印出了60),但函数返回后main中的found、pre、suc又变回NULL,导致输出“didnt work”。


问题原因

C语言中参数传递采用值传递:当你把指针作为参数传入函数时,函数会创建一个该指针的副本。你在函数内部修改的只是这个副本的指向,并不会影响main函数中原来的指针变量。比如found=root;这行代码,只是修改了函数内部found副本的值,main里的found还是初始的NULL。

解决方案

将found、pre、suc的参数类型改为指针的指针(struct node**),这样函数就能通过指针的指针修改原指针的指向。

修改后的函数代码

void findPreSuc(struct node *root, struct node** found, struct node** pre, struct node** suc, int key)
{
    // Base case
    if (root == NULL){  
        return ;
    }
    // If key is present at root
    if (root->data == key)
    {
        *found = root;
        printf("\n%d", (*found)->data); //test if root node gets passed to found
        // the maximum value in left subtree is predecessor
        if (root->left_child != NULL)
        {
            struct node* tmp = root->left_child;
            while (tmp->right_child){
                tmp = tmp->right_child;
            }
            *pre = tmp ;
        }
 
        // the minimum value in right subtree is successor
        if (root->right_child != NULL)
        {
            struct node* tmp = root->right_child;
            while (tmp->left_child){
                tmp = tmp->left_child;
            }
            *suc = tmp ;
        }
        return ;
    }
 
    // If key is smaller than root's key, go to left subtree
    if (root->data > key)
    {
        *suc = root ;
        findPreSuc(root->left_child, found, pre, suc, key) ;
    }
    else // go to right subtree
    {
        *pre = root ;
        findPreSuc(root->right_child, found, pre, suc, key) ;
    }
}

修改后的main函数调用

在调用findPreSuc时,需要传入指针的地址:

findPreSuc(root, &found, &pre, &suc, 60);

这样修改后,函数内部对*found、*pre、*suc的赋值会直接作用于main中的原指针变量,函数返回后这些指针就能保留正确的指向。


内容的提问来源于stack exchange,提问作者Francesco Lucariello

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 10:23:10