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

双向循环链表deleteB头删操作后末尾出现尾随0的问题排查

双向循环链表头删后输出尾随0的问题

问题表现

实现双向循环链表的头删函数deleteB后,删除头节点遍历链表时,末尾出现多余的0值,异常运行截图如下:
双向循环链表异常输出截图
附原始实现代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct Node
{
    int data;
    struct Node *prev;
    struct Node *next;
} Node;

void deleteB(Node **head)
{
    if (*head != NULL)
    {
        if ((*head)->next == *head)
        {
            *head = NULL;
            return;
        }
        Node *temp = *head;
        (*head)->prev->next = (*head)->next;
        (*head)->next->prev = (*head)->prev;
        *head = (*head)->next;
        free(temp);
        // Node *curr = *head;
        // while (curr->next != *head)
        // {
        //  curr = curr->next;
        // }
        // curr->next = (*head)->next;
        // (*head)->next->prev = curr;
        // *head = (*head)->next;
        // free(temp);
    }
}

void prepend(Node **head, int value)
{
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->prev = NULL;
    newNode->next = NULL;
    newNode->data = value;
    if (*head == NULL)
    {
        *head = newNode;
        (*head)->next = *head;
        (*head)->prev = *head;
        return;
    }
    Node *temp = *head;
    while (temp->next != *head)
    {
        temp = temp->next;
    }
    temp->next = newNode;
    newNode->prev = temp;
    newNode->next = *head;
    *head = newNode;
}

void append(Node **head, int value)
{
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->prev = NULL;
    newNode->next = NULL;
    newNode->data = value;
    if (*head == NULL)
    {
        *head = newNode;
        (*head)->next = *head;
        (*head)->prev = *head;
        return;
    }
    Node *temp = *head;
    while (temp->next != *head)
    {
        temp = temp->next;
    }
    temp->next = newNode;
    newNode->prev = temp;
    newNode->next = *head;
}

void display(Node *head)
{
    printf("\nPrinting the list: ");
    Node *temp = head;
    do
    {
        printf("-->%d", temp->data);
        temp = temp->next;
    } while (temp != head);
}

int main()
{
    Node *head = NULL;
    append(&head, 1);
    append(&head, 2);
    append(&head, 3);
    append(&head, 4);
    // insertAtN(&head, 9, 1);
    deleteB(&head);
    display(head);
    printf("\n");
    return 0;
}

问题根因

deleteB的头删逻辑本身没有问题,bug出在append和prepend两个插入函数没有正确维护双向循环链表的指针:

  • append函数在尾部插入新节点后,没有将原头节点的prev指针指向新的尾节点,导致头节点的prev指针始终指向第一次初始化时的节点,无法正确定位到链表尾部
  • 调用deleteB时,代码尝试通过(*head)->prev拿到尾节点修改其next指针,但实际拿到的是不符合预期的节点地址,真正的尾节点next指针仍然指向被释放的原头节点
  • 遍历链表时,走到尾节点后会访问到已释放的内存空间,该空间被系统覆写为0,因此输出了多余的尾随0,后续从已释放内存中读到原头节点存储的next指针才回到新头节点,终止遍历
  • 额外问题:prepend函数同样存在遗漏,头插新节点后没有将原头节点的prev指针指向新头节点,后续调用头插也会出现指针错误

修复方案

  1. 修复append函数,在设置完新节点的next指针后,补充头节点prev指针的赋值:
void append(Node **head, int value)
{
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->prev = NULL;
    newNode->next = NULL;
    newNode->data = value;
    if (*head == NULL)
    {
        *head = newNode;
        (*head)->next = *head;
        (*head)->prev = *head;
        return;
    }
    Node *temp = *head;
    while (temp->next != *head)
    {
        temp = temp->next;
    }
    temp->next = newNode;
    newNode->prev = temp;
    newNode->next = *head;
    (*head)->prev = newNode; // 补充该行,维护头节点的前驱指针
}
  1. 修复prepend函数,在更新头指针前,补充原头节点prev指针的赋值:
void prepend(Node **head, int value)
{
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->prev = NULL;
    newNode->next = NULL;
    newNode->data = value;
    if (*head == NULL)
    {
        *head = newNode;
        (*head)->next = *head;
        (*head)->prev = *head;
        return;
    }
    Node *temp = *head;
    while (temp->next != *head)
    {
        temp = temp->next;
    }
    temp->next = newNode;
    newNode->prev = temp;
    newNode->next = *head;
    (*head)->prev = newNode; // 补充该行,维护原头节点的前驱指针
    *head = newNode;
}

修复后运行代码,输出结果为-->2-->3-->4,无多余尾随0,逻辑正常。


内容的提问来源于stack exchange,提问作者aditya rawat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 00:03:49