C++链接列表头返回 NULL,即使列表不为空

C++ linkedList head returns NULL even though list is not empty

本文关键字:列表 NULL 链接 表头 返回 C++      更新时间:2023-10-16

我正在尝试在C++中实现链表的pop函数。我的节点和链表类如下所示:

//Node class 
template <class T> 
class Node{
    public:
        T data; 
        Node<T> *next;
        Node(T data, Node<T> *next);
        ~Node();
};
template <class T>
Node<T>::Node(T data, Node<T> *next){
    this->next = next;
    this->data = data;
}
template <class T>
Node<T>::~Node(){
    delete this;
}
//LinkedList class
template <class T> 
class  LinkedList{ 
    public:
        //fields
        Node<T> *head;
        int size;
        //methods
        LinkedList();
        void push(T data);
        T pop();   
        void printList();
};
template <class T>
LinkedList<T>::LinkedList(){
    this->head = NULL;
    this->size = 0;
}
template <class T>
void LinkedList<T>::printList(){
    int i = 1;
    while(head){
        std::cout<<i<<": "<<head->data<<std::endl;
        head = head->next;
        i++;
    }
}
int main(){ 
    LinkedList<int> list;
    for (int i = 1; i < 6; ++i)
        list.push(i);
    list.printList();
    for (int j = 0; j < 3; ++j){
        int output=list.pop();
        printf("popped: %dn", output);
    }
    list.printList();
    return 0;
}

下面是我的弹出函数。问题是这个>头返回 NULL。因此我无法更改其值或访问其数据字段。我使用 print 语句来发现这个>头返回 NULL。如何解决此问题?

template <class T>
T LinkedList<T>::pop(){
    Node<T> *h = this->head;
    //if list is empty
    if (this->size==0){
        return 0;
    }
    //if list has only one node
    if (this->size==1){
        T ret = h->data; 
        this->head = NULL;
        this->size --; 
        return ret; 
    }
    //if list has multiple nodes
    else{
        T ret = this->head->data;
        this -> head = h->next;
        return ret;
    }
    h.~Node<T>();
}

下面如果我的推送功能。我已经测试了这个函数,它工作正常,但如果它没有正确处理节点指针,请告诉我。

template <class T>
void LinkedList<T>::push(T data){
    Node<T> *n = new Node<T>(data, this->head);
    this->head = n;
    this->size++;   
}
template <class T>
Node<T>::~Node(){
    delete this;
}

这是非常非常错误的。你需要完全摆脱它。

更重要的是,printList()正在修改head不应该修改的时候。这就是为什么调用headpop()为 NULL 的原因。使用局部Node*变量迭代列表:

template <class T>
void LinkedList<T>::printList(){
    int i = 1;
    Node<T> *n = head; // <-- here
    while(n){
        std::cout << i << ": " << n->data << std::endl;
        n = n->next;
        i++;
    }
}

此外,pop()没有正确释放节点(如果有的话(,并且并不总是减少size。 它应该看起来更像这样:

template <class T>
T LinkedList<T>::pop(){
    Node<T> *h = this->head;
    //if list is empty
    if (this->size==0){
        return T(); // <-- not 0! or throw an exception instead...
    }
    //if list has only one node
    if (this->size==1){
        T ret = h->data; 
        this->head = NULL;
        this->size--; 
        delete h; // <-- add this!
        return ret; 
    }
    //if list has multiple nodes
    T ret = this->head->data;
    this->head = h->next;
    this->size--; // <-- add this!
    delete h; // <-- not h.~Node<T>()!
    return ret; // <-- moved down here!
}

或者更简单,这个(无需单独处理size==1情况(:

template <class T>
T LinkedList<T>::pop(){
    Node<T> *h = this->head;
    //if list is empty
    if (!h){
        return T();
    }
    //if list has any nodes
    T ret = h->data;
    this->head = h->next;
    this->size--;
    delete h;
    return ret;
}