Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c-替换链表函数_C - Fatal编程技术网

c-替换链表函数

c-替换链表函数,c,C,有人能告诉我为什么替换功能不起作用吗?说主叫replace(1,2,list)。它应该搜索节点,如果节点的值为1,它应该创建一个值为2的新节点来替换它,然后释放分配给第一个节点的内存。我想不出来=( 你的replace()函数有几个问题(在你的最后一个问题中,我觉得还不错) 当您找到具有i但对新节点不做任何操作的节点时,可以调用insert()。基本上,您插入的新节点是新的p,因此您应该将p设置为它 您释放p,并立即尝试将p的next字段设置为一个值。p指向的位置无效,因此您不应该这样做。您应该

有人能告诉我为什么替换功能不起作用吗?说主叫replace(1,2,list)。它应该搜索节点,如果节点的值为1,它应该创建一个值为2的新节点来替换它,然后释放分配给第一个节点的内存。我想不出来=(


你的
replace()
函数有几个问题(在你的最后一个问题中,我觉得还不错)

  • 当您找到具有
    i
    但对新节点不做任何操作的节点时,可以调用
    insert()
    。基本上,您插入的新节点是新的
    p
    ,因此您应该将
    p
    设置为它

  • 您释放
    p
    ,并立即尝试将
    p
    next
    字段设置为一个值。
    p
    指向的位置无效,因此您不应该这样做。您应该使用一个临时变量保存旧的
    p
    ,以便以后可以释放该值。只有在实际操作时才应该这样做重新更换,使其成为先前状况的一部分

  • 我认为这应该包括在内。基本上,这些变化是:

    /* if the current node contains the int I'm looking for... */
    if(p->myInt == i)
    {   /* ... the current node needs to be replaced */
        /* save the current node to delete later (2) */
        IntNodePtr oldNode = p;
    
        /* insert a new node making it the new current node (1) */
        p = insert(j, oldNode->next);
    
        /* free the old node (2) */
        free(oldNode);
    }
    /* and so on */
    

    正如Mark指出的,您的
    free(p)
    具有未定义的行为

    p->next = replace(i, j, p->next);
    
    由于您试图将
    p->next
    分配给指针值,但未定义
    p->next
    内存位置本身,因此变得无效

    但是为什么要使这个替换函数递归呢?一个简单的while循环就足够了

    IntNodePtr replace(int i, int j, IntNodePtr p) {
        if(p == NULL)
            return NULL;
        IntNodePtr prevPtr = NULL;
        while(p){
            if(p->myInt == i){
                IntNodePtr temp = insert(j, p->next);
                if(prevPtr)
                     prevPtr->next = temp;
                free(p);
                break;
            }
            prevPtr = p;
            p = p->next;
        }
    }
    

    您也错误地使用了insert函数,因为您没有将以前的节点连接到新创建的节点。

    您能编辑代码并发布它吗jeff?我对这些内容感到非常困惑和沮丧,仍然不理解它。我也喜欢我的旧函数,但函数必须是不可变的,我的旧one是可变的。@mike:你几乎做到了。它的结构基本上与
    delete()类似
    函数。希望您现在能更清楚地看到它。非常感谢Jeff,终于看到了我现在的错误所在。有时我只需要查看正确的代码,然后才能理解代码错误的原因。请注意,您始终需要将列表中的第一个链接传递给您的
    replace
    函数。否则,您将最后打破了清单。到目前为止,你已经有了2到3个答案。我知道这可能是假设的,但是。。。
    IntNodePtr replace(int i, int j, IntNodePtr p) {
        if(p == NULL)
            return NULL;
        IntNodePtr prevPtr = NULL;
        while(p){
            if(p->myInt == i){
                IntNodePtr temp = insert(j, p->next);
                if(prevPtr)
                     prevPtr->next = temp;
                free(p);
                break;
            }
            prevPtr = p;
            p = p->next;
        }
    }