使用迭代器删除 doublearrayList 的最后一个节点
Posted
技术标签:
【中文标题】使用迭代器删除 doublearrayList 的最后一个节点【英文标题】:Delete the last node of a doublyarrayList with an iterator 【发布时间】:2022-01-09 10:57:51 【问题描述】:当我调用remove()
时,我正在尝试删除最后一个节点,而我的当前节点位于最后一个节点。
每次我尝试删除最后一个节点时,我的当前和最后一个节点应该是新的最后一个节点。但是,相反,我的最后一个节点被删除了。
有人可以用一个例子来解释我应该怎么做吗?
我可以使用这些方法获取第一个和最后一个节点Node<TYPE>* getLast()
这是我从现在开始的错误代码:
Node<TYPE>* elementToDelete = currentNode;
this->currentNode = currentNode->getPrevious();
Node<TYPE>* newLastNode = currentNode;
Node<TYPE>* nullLastNode = list->getLast()->getNext();
list->getLast()->getPrevious()->setNext(newLastNode);
newLastNode->setNext(nullLastNode);
delete elementToDelete;
list->decreaseSize();
我的清单
#pragma once
#include "List.h"
#include "Node.hpp"
template <class TYPE>
class DoubleLinkedList : public List<TYPE>
public:
DoubleLinkedList()
this->first = nullptr;
this->last = nullptr;
this->nbElements = 0;
~DoubleLinkedList()
while (!isEmpty())
pop();
void push(const TYPE& content) override
Node<TYPE>* newNodeAdded = new Node<TYPE>(content);
//Si vide
if (this->last == nullptr)
this->last = newNodeAdded;
this->first = last;
//C'est le seul endroit ou on va ajouter les deux nodes spéciaux
this->last->setPrevious(new Node<TYPE>(BOFile, true));
this->last->getPrevious()->setNext(last);
this->last->setNext(new Node<TYPE>(EOFile, true));
//fin ajout nodes spéciaux
//Sinon fin
else
newNodeAdded->setNext(last->getNext());
newNodeAdded->setPrevious(this->last);
//Gestion d'un node spécial
this->last->setNext(newNodeAdded);
this->last = this->last->getNext();
this->last->getNext()->setPrevious(last);
enlargeSize();
void pop() override
if (isEmpty()) throw EmptyListException();
Node<TYPE>* temp = this->first;
this->first = temp->getNext();
//Si dernier element
if (temp == this->last)
this->last = nullptr;
//on pop le dernier node alors on efface les deux nodes spéciaux
delete temp->getNext();
delete temp->getPrevious();
//fin gestion effacement
//Sinon
else
//Avant c'était setPrevious(nullptr); Maintenant on gère les nodes spéciaux
this->first->setPrevious(temp->getPrevious());
this->first->getPrevious()->setNext(first);
delete temp;
decreaseSize();
TYPE& front() override
if (isEmpty()) throw EmptyListException();
return *first->getContent();
TYPE& back() override
if (isEmpty()) throw EmptyListException();
return *(last->getContent());
bool isEmpty() const
return this->nbElements == 0;
void enlargeSize()
this->nbElements++;
void decreaseSize()
this->nbElements--;
int size() const override
return this->nbElements;
Node<TYPE>* getFirst()
if (isEmpty()) throw EmptyListException();
return first;
Node<TYPE>* getLast()
if (isEmpty()) throw EmptyListException();
return last;
private:
Node<TYPE>* first;
Node<TYPE>* last;
int nbElements;
;
我的节点
#pragma once
static const int BOFile = -1;
static const int EOFile = 1;
template <class TYPE>
class Node
public:
Node(const TYPE& content)
setContent(content);
this->next = nullptr;
this->previous = nullptr;
this->extremityStatus = 0;
Node(int extremityStatus, bool failsafe) //Le booléen est parce que si le template est int la signature devient ambigue
content = nullptr;
this->next = nullptr;
this->previous = nullptr;
this->extremityStatus = extremityStatus;
~Node()
if (content != nullptr)
delete content;
Node* getNext()
return next;
void setNext(Node* next)
this->next = next;
Node* getPrevious()
return previous;
void setPrevious(Node* previous)
this->previous = previous;
TYPE* getContent()
return content;
void setContent(const TYPE& content)
this->content = new TYPE(content);
bool isBOFNode()
return extremityStatus == BOFile;
bool isEOFNode()
return extremityStatus == EOFile;
private:
Node* next = nullptr;
Node* previous = nullptr;
TYPE* content = nullptr;
int extremityStatus = 0;
;
【问题讨论】:
您的代码显示得还不够多。我们不知道您是如何实现各种成员函数的,我们不知道您的Node
类型是什么样的,也不知道list
是否也是Node
或它自己的结构。我看到的主要事情是缺乏 NULL 测试,这可能重要也可能不重要,具体取决于导致您显示的代码位的先决条件。
我认为你有点过于复杂了。绘制一个小列表的图片,然后在您逐个链接删除要删除的节点时重绘该列表。
@paddy 这里是我的所有课程,我无法更改 push 或 pop,所有内容都需要在 remove 和 insert 中进行 remove 和 insert
如果Node
将List
声明为朋友,该程序将不那么冗长并且具有更紧密的封装。这是friend
的适当用法,因为这些类具有功能耦合。在节点上设置链接指针的公共方法是不合适的,不应公开。 “extremityStatus”也令人费解。它似乎根本不属于该节点。这种事情应该与列表维护无关,并且最好由任何需要它的列表用户与结构捆绑。
什么是“双重数组列表”?你说的是一个双向链表数组吗?你是在说一个像数组一样的双向链表吗?
【参考方案1】:
当currentNode
指向最后一个节点时,您需要告诉list
更新其last
指针,但您的代码并未尝试这样做。如果 list
中只有 1 个节点,您也不会更新 list
的 first
指针,因此您实际上是在使列表为空。
当从双链表中删除 any 节点时,您可以使用更像这样的逻辑:
Node<TYPE>* elementToDelete = currentNode;
currentNode = elementToDelete->getNext();
if (elementToDelete->getNext())
elementToDelete->getNext()->setPrevious(elementToDelete->getPrevious());
if (elementToDelete->getPrevious())
elementToDelete->getPrevious()->setNext(elementToDelete->getNext());
if (list->getLast() == elementToDelete)
list->setLast(elementToDelete->getPrevious());
if (list->getFirst() == elementToDelete)
list->setFirst(elementToDelete->getNext());
delete elementToDelete;
list->decreaseSize();
如果您知道currentNode
是最后一个节点,那么实际上是这样的:
Node<TYPE>* elementToDelete = ...;
currentNode = nullptr;
if (elementToDelete->getPrevious())
elementToDelete->getPrevious()->setNext(nullptr);
list->setLast(elementToDelete->getPrevious());
if (list->getFirst() == elementToDelete)
list->setFirst(nullptr);
delete elementToDelete;
list->decreaseSize();
话虽如此,这种逻辑确实属于您的 list
类的方法,而不是迭代列表的外部代码。
【讨论】:
我不明白 (elementToDelete->getNext())。这是什么意思? 它正在做一个空测试。非空值的计算结果为true
,空值的计算结果为false
。
对不起,我在课堂上没看到。我这几个月才学这门语言
@NicolasPellerin if (elementToDelete->getNext())
在这种情况下是 if (elementToDelete->getNext() != nullptr)
的简写以上是关于使用迭代器删除 doublearrayList 的最后一个节点的主要内容,如果未能解决你的问题,请参考以下文章