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++循环链表的递归基本情况的主要内容,如果未能解决你的问题,请参考以下文章

字符单链表识别数字,字母,其它字符,并分为三个循环链表的算法c++实现

循环链表的基本操作

单向循环链表

(java实现)单向循环链表

线性结构之循环链表实现

数据结构——循环链表