我正在尝试用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: %d\n", output);
}
list.printList();
return 0;
}
下面是我的pop功能。问题是this-&gt; head返回NULL。因此我无法更改其值或访问其数据字段。我使用print语句来发现this-&gt; head返回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++;
}
答案 0 :(得分:2)
template <class T>
Node<T>::~Node(){
delete this;
}
这是非常非常错误的。你需要完全摆脱它。
更重要的是,printList()
正在修改head
。这就是调用head
时pop()
为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;
}