我已经检查过电路板,但却找不到任何帮助。我发现给定基本和一般情况下的递归函数很容易,但这不像我这样做。我应该迭代一个列表,直到我到达链表的尾部。如果下一个节点为NULL,那么我必须将值存储在最后一个节点,删除该节点,然后返回该值。所以它类似于一个dequeue方法,除了它是递归执行的。我究竟做错了什么?
int LinkedList::removeTailRec(Node *n)
{
// check for the base case(s)
if(n->next == NULL)
{
Node *tmp = new Node();
tmp = n;
int val = n->value;
tmp = NULL;
return val;
}
else
return removeTailRec(n->next);
// else call the recursive method
}
答案 0 :(得分:5)
首先,我建议您使用nullptr
而不是NULL。
然后,在您的代码上。你实际上并没有从列表中删除任何内容。
if(n->next == NULL)
{
Node *tmp = new Node();
^^^^^^^^^^
//Useless, and dangerous. This memory is never free'd
tmp = n;
int val = n->value;
tmp = NULL;
^^^^^^^^^^
//You just set a local variable to NULL, you're not deleting anything
return val;
}
如果要删除节点,则必须保留对前一节点的引用(例如,具有双向链表,即具有指向下一个元素的指针和 a指向每个节点中前一个元素的指针,或直接在前一个节点上工作。
将此前一个节点的next
设置为nullptr
,存储节点的值,然后删除Node
指针。
执行此操作的一种方法是使用指向下一个节点的指针:
int LinkedList::removeTailRec(Node *n)
{
//EDIT: Adding a check for n validity
if(!n){
//Here, you should have a way of detecting
//a call to your method with a null pointer
return 0;
}
Node* nextNode = n->next;
// check for the base case(s)
if(nextNode->next == nullptr)
{
//Get the next node value
int val = nextNode->value;
//Set the current node next member to nullptr
n->next = nullptr;
//Free the last node
delete nextNode;
return val;
}
else{
return removeTailRec(n->next);
}
// else call the recursive method
}
答案 1 :(得分:1)
您正在存储结果,但不会从链接列表中删除它。您可以在另一个变量(指针:结果)中返回结果。
Node* getTail(Node *n,int *result){
//u can even free the memory
if(!n->next)
{
result=n->value;
return NULL;
}
n->next=getTail(n->next,result);
}
或者你可以采取其他方式
int getTail(Node *n)
{
if(!n) return 0;
if(n->next)
{
if(!n->next->next)
{
Node *frnode=n->next;
int result=n->next->value;
n->next=NULL;
delete frnode;
return result;
}
getTail(n->next);
}
答案 2 :(得分:1)
您没有删除代码中的最后一个节点,而是泄漏了另一个(临时)节点。 要删除最后一个节点,必须将上一节点中的链接归零。 您的代码应该是
...
if (n == NULL || n->next == NULL)
throw std::out_of_range("node");
if(n->next->next == NULL)
{
int val = n->next->value;
delete n->next;
n->next = NULL;
return val;
}
else ...
请注意c ++不是函数式语言并且没有尾递归的优化这一事实,所以在实际应用中,随着列表变得越来越大,你最终会出现堆栈溢出失败=)使用Haskell或Erlang来实现这一点编程风格,在c ++中使用for
或while
。
答案 3 :(得分:0)
当n是尾节点时,您应该将Node n的上一个Node的下一个字段设置为NULL。