C++ 删除链接列表上的项目
我已经实现了一个链表,但是我发现删除链表中的最后一个元素总是失败的。我检查了我的代码好几次,但没有发现逻辑错误。从头部和中间节点移除效果良好。下面是我的代码:C++ 删除链接列表上的项目,c++,linked-list,C++,Linked List,我已经实现了一个链表,但是我发现删除链表中的最后一个元素总是失败的。我检查了我的代码好几次,但没有发现逻辑错误。从头部和中间节点移除效果良好。下面是我的代码: #include<iostream> using namespace std; template<typename T> class Node{ // private: T val; Node *next; Node *prev; public: Node(T value){
#include<iostream>
using namespace std;
template<typename T>
class Node{ //
private:
T val;
Node *next;
Node *prev;
public:
Node(T value){
val = value;
next = nullptr;
prev = nullptr;
}
~Node(){
if(prev != nullptr){
prev->next = next;
}
if(next != nullptr){
next->prev= prev;
}
}
T& getVal(){ //
return val;
}
Node* getNext(){
return next;
}
Node* getPrev(){
return prev;
}
//insert node after this node
void insert(Node *n){
if(next != nullptr){
next->prev = n;
}
n->next = next;
n->prev = this;
next = n;
}
void deleteNode(){
if(prev != nullptr && next != nullptr){
prev->next = next;
next->prev = prev;
}
}
};
//build a linked list with deletion and push back function
template<typename T>
class LList{
private:
Node<T> *head;
Node<T> *tail;
public:
LList(){
head = nullptr;
tail = nullptr;
}
~LList(){
if(nullptr != head){
while(head->getNext() != nullptr){ //
delete head->getNext();
}
delete head;
}
}
void push_back(T val){
Node<T>* n = new Node<T>(val);
if(head == nullptr){
head = n ;
tail = head;
}
else{
tail->insert(n);
tail = n;
}
}
void deleteItem(T item){
Node<T> *node = head;
//delete head
if(node->getVal() == item){
head = node->getNext();
node->deleteNode();
return;
}
//delete middle and tail
while(node->getVal() != item && node->getNext() != nullptr ){
node = node->getNext();
}
if(node->getVal() == item && node == tail){
tail = node->getPrev();
node->deleteNode();
return;
}
if(node->getVal() == item && node != tail){
node->deleteNode();
return;
}
else {
cout<<"didnt find the item "<<item<<endl;
}
}
void print(){
Node<T> *node = head;
while(node->getNext() != nullptr){
cout<<node->getVal()<<endl;
node = node->getNext();
}
cout<<node->getVal()<<endl;
}
};
int main(){
LList<double> list;
list.push_back(3.13);
list.push_back(2.8);
list.push_back(23);
list.push_back(4);
list.print();
list.deleteItem(3.13);
list.deleteItem(2);
list.deleteItem(4);
list.print();
return 0;
}
#包括
使用名称空间std;
模板
类节点{//
私人:
T值;
节点*下一步;
节点*prev;
公众:
节点(T值){
val=值;
next=nullptr;
prev=nullptr;
}
~Node(){
if(prev!=nullptr){
上一步->下一步=下一步;
}
如果(下一步!=nullptr){
下一步->上一步=上一步;
}
}
T&getVal(){//
返回val;
}
节点*getNext(){
下一步返回;
}
节点*getPrev(){
返回上一个;
}
//在此节点后插入节点
无效插入(节点*n){
如果(下一步!=nullptr){
下一步->上一步=n;
}
n->next=next;
n->prev=这个;
next=n;
}
void deleteNode(){
如果(上一个!=nullptr&&next!=nullptr){
上一步->下一步=下一步;
下一步->上一步=上一步;
}
}
};
//建立具有删除和回推功能的链表
模板
类利斯特{
私人:
节点*头;
节点*尾部;
公众:
李斯特(){
水头=零PTR;
tail=nullptr;
}
~allist(){
if(nullptr!=头){
而(head->getNext()!=nullptr){//
删除head->getNext();
}
删除标题;
}
}
无效推回(T val){
节点*n=新节点(val);
if(head==nullptr){
水头=n;
尾=头;
}
否则{
尾部->插入(n);
尾=n;
}
}
无效删除项(T项){
节点*节点=头部;
//删除头
如果(节点->getVal()==项){
head=node->getNext();
节点->删除节点();
返回;
}
//删除中间和尾部
而(节点->getVal()!=项目和节点->getNext()!=nullptr){
node=node->getNext();
}
如果(节点->getVal()==项目和节点==尾部){
tail=node->getPrev();
节点->删除节点();
返回;
}
如果(节点->getVal()==项目和节点!=尾部){
节点->删除节点();
返回;
}
否则{
cout这里是:
void deleteNode(){
if(prev != nullptr && next != nullptr){
prev->next = next;
next->prev = prev;
}
}
};
对于最后一个元素,我猜next
等于nullptr
,因此整个条件失败。
我不明白的是,为什么删除第一个元素也不会失败,您可能应该对代码进行x检查
[编辑]
下面是我修复此错误的解决方案,它与节点的析构函数基本相同:
void deleteNode(){
if(prev != nullptr){
prev->next = next;
}
if(next != nullptr){
next->prev= prev;
}
};
我认为所有案例都已在这方面得到考虑:
Head := prev == null & next->prev = nullptr (assuming prev for this node was nullptr before)
Middle := prev->next = next & next->prev = prev
Tail := prev->next = null (assuming as above) & next == null
Head&Tail := prev == null & next == null (Only element of the list is deleted, so no references to be changed)
[/编辑]这解释了删除最后一个节点失败的原因;新的最后一个剩余节点有一个悬空的next
指针,它仍然指向失效的节点。在删除第一个节点的情况下,同样的错误也会发生——新的第一个节点有一个悬空的prev
指针——但是没有人经常使用该指针。现在您已经找到了bug,我建议您编辑您的答案以显示如何更正。如果您使用sentry节点,则没有特殊情况。请参阅