C++ 从循环双链表中删除节点

C++ 从循环双链表中删除节点,c++,linked-list,segmentation-fault,doubly-linked-list,circular-list,C++,Linked List,Segmentation Fault,Doubly Linked List,Circular List,我已经编写了将元素插入到循环双链接列表中并显示这些元素的代码。我还应该能够从列表中删除尾部节点,并在列表中搜索特定元素 这是我添加和打印的工作代码: void Circular_DLList::add_to_tail(int a) { DLLNode *temp = new DLLNode; temp->info = a; if (is_empty()) { tail = temp; temp->next = tail;

我已经编写了将元素插入到循环双链接列表中并显示这些元素的代码。我还应该能够从列表中删除尾部节点,并在列表中搜索特定元素

这是我添加和打印的工作代码:

void Circular_DLList::add_to_tail(int a)
{
    DLLNode *temp = new DLLNode;
    temp->info = a;
    if (is_empty()) {   
        tail = temp;
        temp->next = tail;
        temp->prev = tail;
    }
    else {
        temp->next = tail->next;
        temp->prev = tail;
        tail = temp;
        tail->prev->next = temp;
    }
}

void Circular_DLList::print_list()
{
    DLLNode *ptr;
    ptr = tail->next;
    do {
        cout<< ptr->info << endl;
        ptr = ptr->next;
    }
    while(ptr != tail->next);
}
任何关于如何解决这一问题的建议都是非常好的。我尝试过调试,但我似乎无法找出问题所在,或者它到底与什么有关。
谢谢

如果你仔细看的话,这个问题很明显。您的删除功能正在断开链接列表的循环链。为什么呢请参见下面的删除功能:

int Circular_DLList::delete_from_tail()
{
    int a = tail->info;
    DLLNode *temp;

    if(tail == tail->next) {
        delete tail;
        tail = NULL;
    }
    else {
        tail = tail->prev;
        delete tail->next;
        tail->next = NULL;
    }
    return a;
}
else条件中
您正在设置
tail->next=NULL
,这实际上是一个bug,因此打破了链。所以,当调用print时,它假定循环链是完整的,因此不小心尝试访问空指针,这反过来导致分段错误

修复非常简单,请参见以下代码:

int Circular_DLList::delete_from_tail()
{
    int a = tail->info;
    if(tail == tail->next) {
        delete tail;
        tail = NULL;
    }
    else {
        temp = tail;
        tail = tail->prev;
        tail->next = temp->next;        // To maintain the circular chain
        tail->next->previous = tail;    // Since this element's previous also point to the node about to be deleted
        delete temp;
        temp = NULL;
    }
    return a;
}

如果你仔细观察,这个问题是很明显的。您的删除功能正在断开链接列表的循环链。为什么呢请参见下面的删除功能:

int Circular_DLList::delete_from_tail()
{
    int a = tail->info;
    DLLNode *temp;

    if(tail == tail->next) {
        delete tail;
        tail = NULL;
    }
    else {
        tail = tail->prev;
        delete tail->next;
        tail->next = NULL;
    }
    return a;
}
else条件中
您正在设置
tail->next=NULL
,这实际上是一个bug,因此打破了链。所以,当调用print时,它假定循环链是完整的,因此不小心尝试访问空指针,这反过来导致分段错误

修复非常简单,请参见以下代码:

int Circular_DLList::delete_from_tail()
{
    int a = tail->info;
    if(tail == tail->next) {
        delete tail;
        tail = NULL;
    }
    else {
        temp = tail;
        tail = tail->prev;
        tail->next = temp->next;        // To maintain the circular chain
        tail->next->previous = tail;    // Since this element's previous also point to the node about to be deleted
        delete temp;
        temp = NULL;
    }
    return a;
}

你知道循环链接列表的概念实际上是没有尽头的,对吗?@UsamaZafar是的,但我们正在使用一个名为tail的节点,所以这只是一个简单的说法。我将编辑帖子以澄清删除时是否发生错误?我猜不是。我想这是在删除后打印时发生的,对吗?@UsamaZafar是的,调试器告诉我这是在调用print时发生的,这就是为什么我不确定如何进行修复,请给我一点时间来写答案。你知道循环链接列表的概念实际上是没有尽头的吗?@UsamaZafar是的,但我们正在使用一个名为tail的节点,所以这只是一种简单的表达方式。我将编辑帖子以澄清删除时是否发生错误?我猜不是。我想它是在删除后打印出来的,对吗?@UsamaZafar是的,你是对的,调试器告诉我它是在调用print时发生的,这就是为什么我不确定如何着手修复它。请给我一点时间写下答案。非常感谢,你不知道我有多感激,也非常感谢你的解释。它工作得很好@B哦,很高兴这很有帮助。非常感谢,你不知道我有多感激你,也非常感谢你的解释。它工作得很好@B他们很高兴这有帮助。