如何使用递归

时间:2020-11-12 20:06:58

标签: c++ recursion linked-list

因此,我尝试从链表中的特定节点删除,但问题不是出自从该节点到另一端的删除,而是来自尝试从最后一个节点删除至特定节点时使用递归。

这是我目前拥有的(从节点删除到最后一个节点)


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(以清除事情有点了

2 个答案:

答案 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;
    }
}

Live Demo

话虽如此,但是双向链接列表更适合此任务,因为您根本不需要从列表的开头进行迭代,因此可以从指定的节点开始,例如:

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;
}

Live Demo