c++循环链表的递归基本情况
Posted
技术标签:
【中文标题】c++循环链表的递归基本情况【英文标题】:Recursive base case for c++ circular linked list 【发布时间】:2018-10-24 18:03:06 【问题描述】:这都是假设,
我有一个这样的结构:
struct node
int data;
node* next;
;
和一个只有一个头指针的循环链表,我将如何为一个计算循环链表节点的递归函数设置一个基本情况?我什至不知道从哪里开始,因为我集思广益,很快意识到行不通,因为列表中的最后一个节点直接指向头部而不是 NULL。
示例函数:
int count(node *head)
int listCount = 0;
if(base case)
then return 0;
else
calculate listCount
count(head->next);
return listCount
【问题讨论】:
您能否包含实际的 C++ 代码,而不仅仅是一些无法编译的虚拟代码?链表是一种极其常见的数据结构,所以如果您不熟悉它们是什么,那么在一些open courseware 中进行入门是个好主意。 我正在处理一个构建循环链表并使用固定“头”指针的目标文件,我想在单独的 cpp 文件中实现此循环链接的递归函数列表。我无法发布代码,因为我什至不知道从哪里开始递归函数的基本情况。我接受的每个选项都会导致无限递归调用。 所以我真正难过的是,我如何在递归函数中达到一个基本情况,该函数涉及一个只有一个头指针的循环链表(最后一个节点指向头) . count 是节点的成员吗?如果 node 是您的函数知道的唯一状态,则根据定义,这对于循环列表是不可能的。 对不起,这是一个本地 int 变量,让我编辑帖子以反映这一点。 【参考方案1】:你可以把循环链表变成线性链表
int wrapper_function(node*head)
node*current = head;
head = head -> next;
current -> next = NULL;
count(head);
current -> next = head;
head = current;
return 0;
int count(node *head)
int count = 0;
if(!head)
then return 0;
else
calculate count
count(head->next);
return;
【讨论】:
嗯,我从来没想过,这是唯一可行的方法吗? 对不起,我的意思是限制只有一个函数参数“node *head”并且不使用迭代方法。 好办法,即使你的循环链表不允许修改,你也可以将链表连接回循环形式:)) 我想我会试试你发布的方法,非常感谢! 哈哈,这是为我的实验室准备的,我不确定我们是否能打破这个圈子,但我会这样做,并希望一切顺利!这就是我喜欢 CS 的原因,希望有一天我也能帮助其他人。【参考方案2】:为了确保您将在链表中找到某种起点(可能是您的第一个指针左右),例如,我们将其称为“根”,这样该类将如下所示:
class circle_list
node *root;
...
public:
int count(node *head);
;
现在你可以从这个节点迭代一个基本情况,如果你和根节点在同一个指针上,你返回 0。它会在第一次迭代中返回,所以你可以通过这个问题几种方法,例如,您可以将 head(默认参数)作为“nullptr”发送并检查“head == nullptr”是否在基本情况之后将 head 设置为 root:
int count(node *head = nullptr)
if (head == root)
return 0;
if (head == nullptr)
head = root;
return 1 + count(head->next);
这里有很多可能性,当然这只是可能的想法之一。
【讨论】:
【参考方案3】:好吧,我们必须区分:
空列表,head 为 nullptr 我们位居榜首 我们在列表中间 我们位于列表的末尾,即。 e.我们再次到达头部为了能够区分,您需要跟踪头部!在给定的情况下,通过简单的迭代来完成任务会更容易,所以让我们开始吧:
unsigned int count(node* head)
if(head == nullptr)
return 0;
unsigned int n = 1;
node* current = head->next; // start at next element!
while(current != head) // only way to detect end!
++n;
current = current->next;
return n;
现在,如果您坚持使用递归函数:由于我们需要跟踪头部,我们需要两个指针。没办法。但是我们可以提供一个单独的入口函数,只接受头部,然后将两个指针传递给实际的递归函数:
unsigned int count(node* head)
if(head == nullptr)
return 0;
return count(head, head->next);
unsigned count(node* head, node* current)
if(current == head) // our end condition!
return 1;
return 1 + count(head, current->next);
【讨论】:
【参考方案4】:假设你有一些指向 head 的固定指针,iterator
指向 head:
count(node *head, node *iterator, int *numOfElem)
if(head==iterator)
return;
else
(*numOfElem)++;
count(head, iterator->next, numOfElem);
【讨论】:
我忘了说我唯一可以使用的函数参数是“node *head”。 在 C++ 中,您需要将 reference 而非指针传递给可变参数。这不是必需的,因为您始终可以使用return 1 + count(head, iterator->next)
并具有常规返回类型。以上是关于c++循环链表的递归基本情况的主要内容,如果未能解决你的问题,请参考以下文章