努力将双重链接的通用列表转移到循环中.(segfault)



所以我有这个非圆形双链接列表样本,我发现它很难将其传输到圆形列表中。(在//上添加的行上的segfault)任何建议都很好。提前致谢。另外,我是否应该使用过载来处理不同类型的输入?我如何操纵它们?一个与适当示例的链接(真的找不到一个)会让我开心。

main.cpp

#include <iostream>
#include "dlring.cpp"
int main()
{
    dlring<int> dlist;
    dlist.Append( 11 );
    dlist.Push( 100 );
    while(dlist)
    std::cout << dlist.pop_back()  << " ";
}

dlring.h

           template <typename T>
        class dlring
        {
            struct node
            {
                T data;
                node* prev;
                node* next;
                node(T t, node* p, node* n) : data(t), prev(p), next(n) {}
            };
            node* head;
            node* tail;
        public:
            dlring() : head(nullptr), tail (nullptr) {}
            bool empty() const { return ( !head || !tail ); }
            operator bool() const { return !empty(); }
//Yes, I also wish to implement this bool stuff otherwise.
            void Append(T);
            void Push(T);
            T pop_back();
            T pop_front();
            ~dlring()
            {
                while(head)
                {
                    node* temp(head);
                    head=head->next;
                    delete temp;
                }
            }
        };

dlring.cpp

#include "dlring.h"
#include <iostream>
template <typename T>
void dlring<T>::Append(T data)
{
    tail = new node(data, tail, head); //changed NULL=>head
    if( tail->prev )
    {
        tail->prev->next = tail;
        head->prev = tail; //added
    }
    if( empty() )
        head = tail;
}
template <typename T>
void dlring<T>::Push(T data)
{
    head = new node(data, tail, head);   //changed NULL=>tail
    if( head->next )
    {
        head->next->prev = head;
        tail->next = head; //added
    }
    if( empty() )
        tail = head;
}
template<typename T>
T dlring<T>::pop_back()
{
    if( empty() )
        std::cout<<"List empty";
    node* temp(tail);
    T data( tail->data );
    tail = tail->prev ;
    if( tail )
    {
        tail->next = head; //null=>head;
        head->prev = tail; //added
    }
    else
        head = nullptr; //NULL=>nullptr
    delete temp;
    return data;
}
template<typename T>
T dlring<T>::pop_front()
{
    if( empty() )
        std::cout<<"List empty";
    node* temp(head);
    T data( head->data );
    head = head->next ;
    if( head )
    {
        head->prev = tail; //NULL=>nullptr=>tail
        tail->next = head;
    }
    else
        tail = nullptr; //NULL=>nullptr
    delete temp;
    return data;
}

您的问题在pop_back函数中:

node * temp(tail);
T data(tail->data);
tail = tail->prev;
if(tail)
{
    tail->next = head; //null=>head;
    head->prev = tail; //added
}
else
{
    head = nullptr; //NULL=>nullptr
}
delete temp;

当列表中只有一个节点时,tail不是null-这意味着要满足if条件,并且下面的代码将被点击:

tail->next = head; //null=>head;
head->prev = tail; //added

但是此代码无济于事,因为tailhead是同一件事。然后,您删除列表中唯一的节点,而headtail不再指向任何内容。要解决此问题,您需要一种更好的方法来检测删除后列表是否为空,并稍微更改删除代码:

if (tail != temp)
{
    tail->next = head; //null=>head;
    head->prev = tail; //added
}
else
{
    head = nullptr; //NULL=>nullptr
    tail = nullptr;
}
delete temp;
temp = nullptr;

最新更新