双 STL 链表push_front错误

Double STL Linked List push_front error

本文关键字:front 错误 push STL 链表      更新时间:2023-10-16

我正在努力实现 STL 双链表。我几乎是 c++ 和 OOP 编程的新手,我对 C 语言几乎有很好的了解,但所有这些新概念都很难掌握和实现数据结构。我正在尝试使用迭代器模式和模板制作一个遵循 STL 风格的良好通用 ADT。没有语法错误,相反,元素插入(pushFront 函数)存在很大的逻辑问题,只插入最后一个元素(检查主函数),我尝试调试但仍然找不到问题。希望有人可以帮助我:-)

这些是我的代码片段

节点类:

//Forward declaration
template<class T>
class LinkedList;

//Node should be structure?
template<class T>
class Node
{
    friend class LinkedList<T>;
public:
    Node(): pPrev_(nullptr), pNext_(nullptr) {}
    Node(const T& value): data_(value), pPrev_(nullptr), pNext_(nullptr) {}
    /*
     * Implementing double linked list node
     * data_: node's data of type T
     * pNext_: pointer to the next node
     * pPrev_: pointer to the previous node
     */
// if I put Private there some errors with private stuff, I have declared also LInkedList as friend
    T data_;
    Node<T>* pPrev_;
    Node<T>* pNext_;
}; 

迭代器类:

template<class T>
class ListIterator
{
    // Declaring LinkedList friend class, now
    //LinkedList can access to all data in this class
    friend class LinkedList<T>;
public:
    //Constructors
    ListIterator();
    ListIterator(Node<T>* node);
    //Destructor
    ~ListIterator();
    // Assignement Overload
    //ListIterator<T> operator=(const)
    //Deferencing Overload
    T operator*();
    //Prefix Overload
    ListIterator<T> operator++();
    ListIterator<T> operator--();
    //Postfix Overload
    ListIterator<T> operator++(int);
    ListIterator<T> operator--(int);
    //Relational Overload
    bool operator==(const ListIterator<T>& Node);
    bool operator!=( const ListIterator<T>& Node);

private:
    // Actual node holden by iterator
    Node<T>* curNode_;
};
/*
 LIST_ITERATOR IMPLEMETATION
*/
template <class T>
ListIterator<T>::ListIterator(): curNode_(nullptr){}
template <class T>
ListIterator<T>::ListIterator(Node<T>* node): curNode_(node) {}
//Destructor
template <class T>
ListIterator<T>::~ListIterator() {}
//Deferencing Overload
template <class T>
T ListIterator<T>::operator *()
{
    //Return the VALUE of the current node holden by iterator
    return this->curNode_->data_;
}
//Prefix Overload
template <class T>
ListIterator<T> ListIterator<T>::operator ++()
{
    /*
     * Check if the next node is a valid node, then
     * the current node will be the next node
     * Return the value of the current node
     */
    if (this->curNode_->pNext_ != nullptr)
        this->curNode_ =this->curNode_->pNext_; //Like it++, jump to the next node
    return *this;
}
template <class T>
ListIterator<T> ListIterator<T>::operator --()
{
    /*
     * Check if the previous node is a valid node, then
     * the current node will be the previous node
     * Return the value of the current node
     */
    if( this->curNode_->pPrev_ != nullptr)
        this->curNode_ = this->curNode_->pPrev;
    return *this; //?? why return this
}
//Postfix Overload
template <class T>
ListIterator<T> ListIterator<T>::operator ++(int)
{
    ListIterator<T> temp= *this;
    ++(*this);
    return temp;
}
template <class T>
ListIterator<T> ListIterator<T>::operator --(int)
{
    ListIterator<T> temp= *this;
    --(*this);
    return temp;
}
// Inequalities Overload
template <class T>
bool ListIterator<T>::operator==(const ListIterator<T>& node)
{
    /*
     * Check if the address of the current node is equal to the address of node param
     */
    return( this->curNode_== node.curNode_);
}
template <class T>
bool ListIterator<T>::operator!=(const ListIterator<T>& node)
{
    return  !((*this) == node);
}

链接列表类:

template<class T>
class LinkedList
{
public:
    typedef ListIterator<T> iterator;
    //Constructors
    LinkedList();
    LinkedList(const LinkedList<T>& copyList);
    //Destructor
    ~LinkedList();
    //List Status Methods
    bool isEmpty();
    unsigned int getSize();
    iterator begin();
    iterator end();
    //Should parameters be constant and passed by reference &? let's check with tester if there are some troubles
    //Insert Methods
    void pushFront(const T value);
    void pushBack(const T value);
    void insertAt(const T value,iterator& atPos);
    //Remove Methods
    void popFront();
    void popBack();
    void removeAt(iterator& pos);
    void clear();
    /** Addtional methods
     *
     * sort
     * min,max,
     * clear,
     * overload <<
     * print
     */

private:
    /*
     * Keeping a pointer to head and tail of the list;
     * Size_: number of  list's element
     */
    Node<T>* Head_;
    Node<T>* Tail_;
    unsigned int Size_;

};

// LIST IMPLEMENTATION
// Constructors
template < class T>
LinkedList<T>::LinkedList()
{
    /*
     * Create a new empty node, head and tail are/share the same node at this step.
     * Assign to head's pointer to next node NULL
     * Assign to tail's pointer to previous node NULL
     */
    this->Head_=this->Tail_= new Node<T>;
    this->Head_->pNext_= nullptr;
    this->Tail_->pPrev_= nullptr;
    this->Size_=0;
}
// WIP TO CHECK
template <class T>
LinkedList<T>::LinkedList(const LinkedList<T>& list){
    this->Head_=this->Tail_= new Node<T>;
    this->Head_->pNext_= nullptr;
    this->Tail_->pPrev_= nullptr;
    this->Size_=0;
    // create iterator to loop inside the container
    for(iterator it= list.begin ; it != list.end(); it++)
        this->pushBack(*it);
}
//Destructor
template <class T>
LinkedList<T>::~LinkedList()
{
    this->clear(); //delete all nodes
    delete this->Tail_;
}
//Begin & end()
template <class T>
ListIterator<T> LinkedList<T>::begin()
{
    iterator it= this->Head_;
    return it;
}
template <class T>
ListIterator<T> LinkedList<T>::end()
{
    iterator it= this->Tail_;
    return it;
}
//Clear
template< class T>
void LinkedList<T>::clear()
{
    iterator it= this->begin();
    while(it != this->end())
        this->removeAt(it);
}

这些是给我错误的方法:

//Insert At
    template <class T>
    void LinkedList<T>::insertAt(const T value, iterator& atPos)
    {
        Node<T>* newNode= new Node<T>;
        newNode->data_= value;
        //Add links
        if( atPos == this->begin())
        {
            newNode->pNext_=this->Head_;
            this->Head_=newNode;
        }
        else if ( atPos == this->end())
            //Still to implement
            this->Tail_= newNode;
        else
        {
            newNode->pNext_ = atPos.curNode_;
            atPos.curNode_->pPrev_ = newNode;
            atPos.curNode_->pPrev_->pNext_ = newNode;
            newNode->pPrev_=atPos.curNode_->pPrev_;
        }

        atPos.curNode_= newNode;
        this->Size_++;
    }
    template <class T>
    void LinkedList<T>::pushFront(const T value)
    {
        iterator it= this->begin();
        this->insertAt(value, it);
    }

这里有一些测试ADT的行:

#include <iostream>
#include <stdlib.h>
#include <string>
#include "LinkedList.h"
using namespace std;
int main() {

    Node<int> nd(4);
    ListIterator<int> it;
    LinkedList<int> lst;
    for(int i=0; i < 25;i++)
        lst.pushFront(i);

    for(it=lst.begin(); it != lst.end();it++)
    {
        cout << *it << endl;
        system("Pause");
    }
    cout << "iia";

    system("Pause");
    return 0;
}

输出中没有错误:

24
Press any key to continue . . .
23
Press any key to continue . . .
22
Press any key to continue . . .
...
Press any key to continue . . . 
0
Press any key to continue . . .
iiaPress any key to continue . . .

附言不要在可以避免的地方使用this。代码将更易于阅读。