2012-07-30 70 views
0

所以我在夏天的OO类中,我们需要编写一个函数来从链表中删除一个节点。我非常接近,但有几个问题。我的代码成功地遍历链表,但是一旦循环找到节点,实际上就会删除节点。这是我目前的功能:C++从列表中间删除节点

template< class NODETYPE > 
bool List<NODETYPE>::removeMiddle(NODETYPE &value, int i) 
{ 
    ListNode <NODETYPE> * tempPtr = firstPtr; 
    ListNode <NODETYPE> * prevPtr ; 
    int counter=1; 

    if (isEmpty()) 
     return false; 
    if (i <= 0) 
     return false; 

    while (tempPtr != 0 && counter < i){ 
     counter++; 
     if (firstPtr == lastPtr) 
     firstPtr = lastPtr = 0; 
    else 
     firstPtr = firstPtr->nextPtr; 
      prevPtr = tempPtr; 
      tempPtr = tempPtr->nextPtr; 
     } 

     if (counter == i){ 
      value = tempPtr->data; // data being removed 
      delete tempPtr; 
     } 
    } 

    return true; 
    RecordCounter--; 
} 
+1

有什么问题,具体是?你能描述一下这个问题吗? – 2012-07-30 02:15:42

+0

请修复缩进 – 2012-07-30 02:19:24

+0

另外,为宏保留大声的大写标识是一个不错的主意。 – 2012-07-30 02:29:49

回答

3

您忘记更改上一个节点,以便它不再指向您删除的节点。

你想要的(主要是)类似于:没有任何更多的细节

if (counter == i-1) //next node is the one you want to delete 
{ 
    aux = tempPtr->nextPtr->nextPtr; //retain next next node 
    delete tempPtr->nextPtr;   //delete next node 
    tempPtr->nextPtr = aux;   //current node now points to the node after the deleted one 
} 
+0

是的!谢谢你解决了我的删除错误。还有一个(小的)缺陷。我不确定你是否能够提供帮助。当节点被删除时,输出到控制台应该说是被删除的节点的值。出于某种原因,它说错了。对于示例 - 这份名单是:1 2 3 4 5 输入位置删除:3 1从列表中删除 名单是:1个2 3 4 5 – 2012-07-30 02:23:34

+0

@ConnorBlack可能是因为你返回你递减计数器之前? – 2012-07-30 02:24:23

+0

很好解决,但这不是问题。 – 2012-07-30 02:28:02

2

我的第一个猜测是,你不是在维护该列表的完整性。尽管我在C++中很生疏。

您正在删除tempPtr并跟踪prevPtr ...但不会在删除后重新链接列表的两半。

prevPtr->nextPtr = tempPtr->nextPtr 
0

您忘记调整列表中的链接。该节点在delete之后仍然存在,但现在它无效。哎呀!

此功能非常有用:它指向你想要删除的节点nextPtr通过

NODETYPE* unlink(NODETYPE*& pNode) 
{ 
    NODETYPE* const result = pNode; 

    pNode = pNode->nextPtr; 
    return result; 
} 

呼叫。你得到一个指向节点的指针,列表重新链接,这样节点就不在列表中了。现在你可以用delete那个节点。

如果您只有一个指针直接指向要删除的节点,并且该列表单链接,该怎么办?那么,唐纳德克努特曾经问过他作为计算机编程艺术的一个练习(如果我没有记错的话)。一种解决方案是将数据与下一个节点交换,然后删除下一个节点。