双向链表实现中的指针算法问题

问题描述 投票:0回答:0

我正在尝试实现双向链表以用于学习目的。这是我的第一次尝试,所以一路上我遇到了一些麻烦。代码是:

class List 
{
public:

    class Iterator;

    using value_type = int;
    // using allocator_type = Allocator;
    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;
    using reference = Node&;
    using const_reference = const Node&;
    // using pointer = std::allocator_traits<Allocator>::pointer;
    using pointer = Node*; // TODO remove after lifting
    // using const_pointer = std::allocator_traits<Allocator>::const_pointer;
    using const_pointer = const Node*;
    using iterator = Iterator;
    using const_iterator = const Iterator;

    class Iterator
    {
    public:
        Iterator() = default;
        Iterator(const Iterator& it): curr{ it.curr } {}
        Iterator(Node* n): curr{ n } {}

        Node* current() { return curr; }
        void operator=(Node* it) { curr = it; }
        Node* operator++() { curr = curr->next; return curr; }
        Node* operator++(int)
        {
            auto temp{ curr }; curr = curr->next; return temp;
        }
        Node* operator--() { curr = curr->prev; return curr; }
        Node* operator--(int)
        {
            auto temp{ curr }; curr = curr->prev; return temp;
        }
        bool operator==(const Iterator& it) const
        {
            return this->curr == it.curr;
        }
        bool operator!=(const Iterator& it) const{ return !( *this == it ); }
        Node& operator*() { return *curr; }
        Node* operator->() { return curr; }
    private:
        Node* curr;
    };

    List() = default;
    List(const std::initializer_list<value_type>& lst);

    value_type front() { return first->val; } // access the first element
    value_type back() { return last->val; } // access the last element

    iterator begin() { return first; }
    const_iterator begin() const { return first; }
    iterator end() { return last; }
    const_iterator end() const { return last; }

    bool empty() const { return sz == 0; } // check whether the container is empty
    size_type size() { return sz; }

    void clear(); // clear the content
    iterator insert(iterator iter, const value_type& elem); // insert elem
    // after iter
    // void emplace(const value_type& elem); TODO find out about that member

    void erase(iterator it);
    void push_back(const value_type& elem);
    void pop_back();
    void push_front(const value_type& elem);
    void pop_front();
    
    ~List()
    {
        clear();
        delete first;
        delete last;
    }

private:
    pointer first{ new Node{0, nullptr, last} };
    pointer last{ new Node{0, first, nullptr} };
    size_type sz{ 0 };
};

void List::clear()
{
    if(empty()) return;

    while(first->next != last)
    {
        erase(first->next);
    }
    sz = 0;
}

我被建议让它在

int
上开始工作,然后将其作为模板。问题是我不能做这样的事情:

 auto temp{list.begin()};
while(temp != list.end()) {...; ++temp;}

我刚收到“Segmentation fault (core dumped)”错误。据我了解,原因在于:

int main()
{
        List lst;
    
        std::cout << &( lst.first ) << " adress of first\n";
        std::cout << &( lst.last ) << " adress of last\n";
        std::cout << &( lst.first->next ) << " adress of first->next\n";  
         
        return 0;
    }

结果:

0x7ffde43c6500 adress of first
0x7ffde43c6508 adress of last
0x5573f5d73eb8 adress of first->next

但是在 List

first->next
的默认构造函数中是“last”。我做错了什么?

编辑:由于#Some programmer dude explain(我的愚蠢错误)上面的代码打印了指向

first
last
的指针位置,所以像这样更改代码:

int main()
{
        List lst;
    
        std::cout << &( *lst.first ) << " adress of first\n";
        std::cout << &( *lst.last ) << " adress of last\n";
        std::cout << &( *(lst.first->next) ) << " adress of first->next\n";  
         
        return 0;
    }

我得到这个输出:

0x55b111d77eb0 adress of first
0x55b111d77ed0 adress of last
0 adress of first->next

而且他还指出问题是错误的初始化顺序 -

first
初始化指向
last
last
甚至被创建之前。

c++ pointers doubly-linked-list
© www.soinside.com 2019 - 2024. All rights reserved.