2011-02-07 127 views
0

谁能告诉我为什么替换功能不起作用?说主叫replace(1,2,列表)。它应搜索节点,如果节点的值为1,则应创建一个值为2的新节点来替换它,然后释放分配给第一个节点的内存。我无法弄清楚=(c - 替换链表功能

typedef struct iNode 
{ 
    int myInt; 
    struct iNode* next; 
} IntNode, *IntNodePtr; 

IntNodePtr insert(int i, IntNodePtr p) 
{ 
    IntNodePtr newp = malloc(sizeof(struct iNode)); 
    newp->myInt = i; 
    newp->next = p; 
    return newp; 
} 

IntNodePtr delete(int i, IntNodePtr p) 
{ 
    /* End of list check */ 
    if(p == NULL) 
     return NULL; 

    /* Check if current node is the one to delete */ 
    if(p->myInt == i) 
    { 
     IntNodePtr temp; 
     temp = p->next; 

     free(p); 
     return temp; 
    } 

    p->next = delete(i, p->next); 
    return p; 
} 

IntNodePtr replace(int i, int j, IntNodePtr p) 
{ 
    if(p == NULL) 
     return NULL; 

    if(p->myInt == i) 
     insert(j, p->next); 

    free(p); 

    p->next = replace(i, j, p->next); 
    return p; 
} 
+0

请注意,您将始终需要将列表中的第一个链接传递给您的`replace`函数。否则,你会最终打破名单。这也适用于2到3个答案。我知道这可能是假设的,但... – JimR 2011-02-07 03:26:18

回答

0

有几个问题你replace()功能(它看起来罚款我在你的最后一个问题)。

  1. 你叫insert()当你发现有i的节点,但你什么都不做与新节点(什么insert()回报)。基本上你要插入的新节点是新p所以你应该设置p它。

  2. 您可以免费使用p并立即尝试将pnext字段设置为值。 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 */ 
+0

你能编辑代码并发布它吗?即时通讯完全困惑和沮丧与这东西,仍然不理解它。我也喜欢我的旧功能,但功能必须是不变的,而我的旧功能是可变的。 – mikecavs 2011-02-07 03:10:26

0

正如马克指出,你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; 
    } 
} 

并且使用的是不正确的插入功能为好,因为你没有连接上一个节点到新创建的节点。