【问题标题】:Incorrect result after removing first node from Linked List从链表中删除第一个节点后结果不正确
【发布时间】:2014-01-19 23:37:49
【问题描述】:

我编写这段代码是为了删除单链表中的第一个节点。

CreateLinkedList(node **headPtr)
{
    int i;
    node *pMyNode;
    pMyNode = (node*)malloc(sizeof(node)); //create space for first node []
    *headPtr=pMyNode;
    for(i=0;i<10;i++)
    {
        pMyNode->element = i; //enter value [0]
        printf("Value is %d addr is %p\n",pMyNode->element,pMyNode);
        pMyNode->nextPtr = (node*)malloc(sizeof(node)); //[0]->[]->NULL
        pMyNode = pMyNode->nextPtr;
    }
    pMyNode->nextPtr=NULL;
}

void PrintLinkedList(node **headPtr)
{
    node *pMyNode;
    int i;
    pMyNode=*headPtr;
    while(pMyNode)
    {
        printf("Value is %d addr is %p\n",pMyNode->element,pMyNode);
        pMyNode = pMyNode->nextPtr;
    }
}

void DeleteANode(node **headPtr)
{
    node *pMyNode; //head->[]->[]->[]->NULL
    pMyNode=*headPtr;
    *headPtr=*headPtr->nextPtr;
    free(pMyNode);

}
int main()
{   
    node *pNode;
    CreateLinkedList(&pNode);
    DeleteANode(&pNode);
    PrintLinkedList(&pNode);
}

我得到的输出是:

删除前

value is 0 addr is 8e75008 
value is 1 addr is 8e75018
value is 2 addr is 8e75028
value is 3 addr is 8e75038
value is 4 addr is 8e75048
value is 5 addr is 8e75058
value is 6 addr is 8e75068
value is 7 addr is 8e75078
value is 8 addr is 8e75088
value is 9 addr is 8e75098

删除后

value is 0 addr is 8e75008 // This node should not be printed
value is 0 addr is 8e75018 
value is 2 addr is 8e75028
value is 3 addr is 8e75038
value is 4 addr is 8e75048
value is 5 addr is 8e75058
value is 6 addr is 8e75068
value is 7 addr is 8e75078
value is 8 addr is 8e75088
value is 9 addr is 8e75098

【问题讨论】:

  • 请显示更完整的代码。您没有显示节点在何处被创建/初始化,或添加到列表中以及调用所有这些的代码。
  • DeletaANode 是否意味着删除列表头部的节点?如果是这样,为什么 8e75018 是您的示例中不应打印的节点? 8375008不应该是不应该打印的节点吗?
  • 正确。我刚刚编辑了我的帖子。
  • 您应该将 PrintLinkedList 中的循环更改为使用while(pMyNode != NULL)。目前它总是循环 10 次,但列表中可能不再有 10 个节点(就像删除一个节点后一样)。
  • 我也试过了。但结果还是一样。

标签: c linked-list


【解决方案1】:

您的问题之一是以下陈述:

*headPtr=*headPtr->nextPtr;

-&gt; 的优先级高于*,因此首先对其进行评估。要首先取消引用指针,您需要括号:

*headPtr=(*headPtr)->nextPtr;

另一个问题是下面的块:

pMyNode=*headPtr;
for(i=0;i<10;i++)
{
    printf("Value is %d addr is %p\n",pMyNode->element,pMyNode);
    pMyNode = pMyNode->nextPtr;
}

您不应该硬编码有多少链接。而是使用while 循环并检查NULL

pMyNode=*headPtr;
while(pMyNode)
{
    printf("Value is %d addr is %p\n",pMyNode->element,pMyNode);
    pMyNode = pMyNode->nextPtr;
}

【讨论】:

    【解决方案2】:

    你的问题出在这行 DeleteANode:*headPtr=*headPtr-&gt;nextPtr;

    我认为应该是*headPtr=(*headPtr)-&gt;nextPtr;

    我不确定为什么您的版本不会像您那样在行上抛出错误/警告。 *headPtr 的分配应该期待另一个指向节点的指针,并且您正在取消对 headPtr->nextPtr 的引用,从而试图将节点结构分配给 *headPtr?!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多