从链接列表c++中删除一个项目

remove an item from a linked list c++

本文关键字:一个 项目 删除 链接 列表 c++      更新时间:2023-10-16

我的项目删除功能有问题

void removeKey(int key) {
ListElement *element = getElement(key);
if (element != nullptr) {
ListElement *nextElement = element->getNext();
ListElement *previousElement = getPreviousElemnt(element);
if (previousElement == nullptr) {//pierwszy element
firstElement = nextElement;
} else if (nextElement == nullptr) { //
previousElement->setNext(nullptr);
} else {
previousElement->setNext(nextElement);
}
delete element;
size--;
}
}
}
ListElement *getPreviousElemnt(ListElement *element) {
ListElement *element1 = firstElement;
if (element1 != nullptr) {
while (element1->getNext() == element) {
return element1;
}
}
return nullptr;
}

移除第一个元素效果良好。当我想从中心或结尾删除一个元素时,程序会删除它左边的所有元素…

您的getPreviousElemnt()循环不正确。它应该看起来更像这样:

ListElement *getPreviousElemnt(ListElement *element) {
ListElement *element1 = firstElement;
while (element1 != nullptr) {
ListElement *nextElement = element1->getNext();
if (nextElement == element) {
return element1;
}
element1 = nextElement;
}
return nullptr;
}

并且您的removeKey()不需要那么多if..elseif..else块,它可以简化为:

void removeKey(int key) {
ListElement *element = getElement(key);
if (element != nullptr) {
ListElement *nextElement = element->getNext();
ListElement *previousElement = getPreviousElemnt(element);
if (previousElement != nullptr) {
previousElement->setNext(nextElement);
}
if (firstElement == element) {
firstElement = nextElement;
}
delete element;
size--;
}
}

然而,如果您根本不使用getElement(),则removeKey()可以大大优化,从而避免必须在列表中循环两次:

void removeKey(int key) {
ListElement *element = firstElement;
ListElement *previousElement = nullptr;
while (element != nullptr) {
if (element->getKey() == key) {
ListElement *nextElement = element->getNext();
if (previousElement != nullptr) {
previousElement->setNext(nextElement);
}
if (firstElement == element) {
firstElement = nextElement;
}
delete element;
size--;
return;
}
previousElement = element;
element = nextElement;
}
}

或者,更新getElement()以选择性地返回上一个元素:

ListElement* getElement(int key, ListElement** previousElement = nullptr) {
if (previousElement) {
*previousElement = nullptr;
}
ListElement *element = firstElement;
ListElement *previousElement1 = nullptr;
while (element != nullptr) {
if (element->getKey() == key) {
if (previousElement) {
*previousElement = previousElement1;
}
return element;
}
previousElement1 = element;
element = element->getNext();
}
return nullptr;
}
void removeKey(int key) {
ListElement* previousElement;
ListElement *element = getElement(key, &previousElement);
if (element != nullptr) {
ListElement *nextElement = element->getNext();
if (previousElement != nullptr) {
previousElement->setNext(nextElement);
}
if (firstElement == element) {
firstElement = nextElement;
}
delete element;
size--;
}
}

您需要修复代码的getPreviousElement。现在它所做的是检查第一个元素是否是所需元素的前一个。如果是,则返回正确。如果否,则退出while循环并返回nullptr。您需要继续循环,直到获得元素为止。我不会发布解决方案,因为它应该是你的一个学习练习。

ListElement *getPreviousElemnt(ListElement *element) {
ListElement *element1 = firstElement;
if (element1 != nullptr) {
while (element1->getNext() != element) {  //<----change this
element1 = element1->getNext();
}
return element1; //<-----return previous
}
return nullptr;
}
相关文章: