因此,我尝试从链表中的特定节点删除,但问题不是出自从该节点到另一端的删除,而是来自尝试从最后一个节点删除至特定节点时使用递归。
这是我目前拥有的(从节点删除到最后一个节点)
void rLL<T> :: recursiveDelete(item<T> * node)
{
if (node != nullptr)
{
item<T> * nodeptr = node -> next;
delete node;
size--;
recursiveDelete(nodeptr);
}
}
现在我必须尝试将其切换。而且我不知道该怎么做。 这是一个学校项目,因此,请尽可能保持简单。
edit:假设列表由1,2,3,4,5,6,7组成,并将节点5放入参数node中,然后应按该特定顺序删除7,6,5(以清除事情有点了
答案 0 :(得分:0)
如果我正确理解这一点,则想删除一个指向您特定节点的节点。如果这样做,我将有2个节点,currentNode和prevNode。向前迭代时,将它们都移动,并在currentNode符合规范时以这种方式移动,您可以删除prevNode。如果我不明白这个问题,请告诉我。
答案 1 :(得分:0)
您问题的答案是在调用delete
之前先执行递归调用 。
但是,即使您能够成功删除指定的节点,您提供的代码仍然存在重大缺陷-它不会将节点之前的next
字段更新指定的节点,因此您最终会使列表保持无效状态,因为该 prior 节点将成为新的尾节点,但是具有一个非null的next
指针无法正确终止列表。
对于单链接列表,您必须从列表的开头进行迭代才能发现要更新的 prior 节点。但是一旦到达指定的节点并知道其上一个节点,就可以对列表的其余部分使用递归算法,例如:
template<typename T>
void rLL<T>::recursiveDelete(item<T> *node, item<T> *previous)
{
if (!node) return;
recursiveDelete(node->next, node);
if (previous) previous->next = nullptr;
--size;
delete node;
}
void rLL<T>::deleteToEnd(item<T> *startNode)
{
if (!startNode) return;
item<T> *node = head;
item<T> *previous = nullptr;
while (node)
{
if (node == startNode)
{
recursiveDelete(node, previous);
return;
}
previous = node;
node = node->next;
}
}
话虽如此,但是双向链接列表更适合此任务,因为您根本不需要从列表的开头进行迭代,因此可以从指定的节点开始,例如:
void rLL<T>::deleteToEnd(item<T> *startNode)
{
if (!startNode) return;
deleteToEnd(startNode->next);
item<T> *previous = startNode->previous;
if (previous) previous->next = nullptr;
if (head == startNode) head = nullptr;
tail = previous;
--size;
delete startNode;
}