首页 > 其他分享 >链表递归题型

链表递归题型

时间:2023-12-17 20:23:57浏览次数:52  
标签:题型 单链 NodeType 递归 next 链表 节点 指针

递归的定义

  在定义一个过程或函数时出现调用本过程或本函数的成分,称之为递归。若调用自身,称之为直接递归。若过程或函数p调用过程或函数q,而q又调用p,称之为间接递归。

递归算法的设计

  递归的求解过程均有这样的特征:先将整个问题划分为若干个子问题,通过分别求解子问题,最后获得整个问题的解。而这些子问题具有与原问题相同的求解方法,于是可以再将它们划分成若干个子问题,分别求解,如此反复进行,直到不能再划分成子问题,或已经可以求解为止。这种自上而下将问题分解、求解,再自上而下引用、合并,求出最后解答的过程称为递归求解过程,这是一种分而治之的算法设计方法。

简单递归算法设计方法:

例题

有一个不带表头节点的单链表,其节点类型如下:

typedef struct NodeType
{
   ElemType data;
   struct NodeType *next;
 }NodeType;

设计如下递归算法: 

1   求以h为首指针的单链表的节点个数。

2   正向显示以h为首指针的单链表的所有节点值。 

3   反向显示以h为首指针的单链表的所有节点值。 

4   删除以h为首指针的单链表中值为x的第一个节点。 

5   删除以h为首指针的单链表中值为x的所有节点。 

6   输出以h为首指针的单链表中最大节点值。 

7   输出以h为首指针的单链表中最小节点值。 

8   删除并释放以h为首指针的单链表中所有节点。

解:设h为不带头节点的单链表(含n个节点),如图所示,h->next 也是一个不带头节点的单链表(含n-1个节点),两者除了相差一个节点外,其他都是相似的。

1   求以h为首指针的单链表的节点个数

设count(h)用于计算单链表h的结点个数,其递归模型如下:

对于的递归算法如下:

int count(NodeType *h)
{
  if(h==NULL)
    return 0;
  else
    return (1+count(h->next));
}

 

 

2   正向显示以h为首指针的单链表的所有节点值

设traverse(h)用于正向扫描单链表h,其递归模型如下:

对于的递归算法如下:

void traverse(NodeType *h)
{
  if(h!=null)
 {
   printf("%d",h->data);
   traverse(h->next);
  }
}

 

3   反向显示以h为首指针的单链表的所有节点值

设revtraverse(h)用于反向扫描链表h,其递归模型如下:

对于的递归算法如下:

void revtraverse(NodeType *h)
{
  if(h!=null)
 {
   revtraverse(h->next);
   printf("%d",h->data);
  }
}

 

 

4   删除以h为首指针的单链表中值为x的第一个节点

设delnode(h,x)用于删除单链表h中第一个值为x的结点,其递归模型如下:

对于的递归算法如下:

void delnode(NodeType *&h,ElemType x){  
    NodeType *p;  
    if(h!=NULL) {   
        if(h->data == x){    
            p = h;    
            h = h->next;    
            free(p);
        }   
    else    
        delnode(h->next,x);  
    }
}

 

 

5   删除以h为首指针的单链表中值为x的所有节点

设delall(h,x)用于删除单链表h中所有值为x的结点,其递归模型如下:

对于的递归算法如下:

void delall(NodeType *&h, ElemType x)
{
  NodeType *p;
  if(h!=NULL)
 {
   if(h->data == x)  //若首结点的值为x
  {
    p = h;
    h = h->next;
    free(p);
    delall(h,x);   //在后继结点递归删除
   }
   else              //若首结点值不为 x
     delall(h->next,x);  //在后继结点递归删除
   }
}

6   输出以h为首指针的单链表中最大节点值

设maxv(h)用于计算单链表h的最大结点值,其递归模型如下(其中MAXV(x,y) 表示返回x和y的较大者):

对于的递归算法如下:

ElemType maxv(NodeType *h){  
    ElemType m;  
    if(h->next == NULL)    //只有一个结点的情况    
        return (h->data);  
    m = maxv(h->next);     //求后继结点的最大值    
    if(m>h->data)    
        return m;  
    else    
        return h->data;
}

 

7   输出以h为首指针的单链表中最小节点值

设minv(h)用于计算单链表h的最小结点值,其递归模型如下(其中MIN(x,y)表示返回x和y的较小者):

对于的递归算法如下:

ElemType minv(NodeType *h)
{
  ElemType m;
  if(h->next == NULL)
    return h->data;
  m = minv(h->next);
  if(m>h->data)
    return h->data;
  else
    return m;
}

 

8   删除并释放以h为首指针的单链表中所有节点

设release(h)的功能是删除并释放单链表h中所有结点,其递归模型如下:

对于的递归算法如下:

void release(NodeType *h)
{
  if(h!=NULL)
 {
  release(h->next);
  free(h);
  }
}

 

参考

https://mp.weixin.qq.com/s/GiSqzg5827JyHrPQO0Z-hA

 

递归的定义

在定义一个过程或函数时出现调用本过程或本函数的成分,称之为递归。若调用自身,称之为直接递归。若过程或函数p调用过程或函数q,而q又调用p,称之为间接递归。

递归算法的设计


递归的求解过程均有这样的特征:先将整个问题划分为若干个子问题,通过分别求解子问题,最后获得整个问题的解。而这些子问题具有与原问题相同的求解方法,于是可以再将它们划分成若干个子问题,分别求解,如此反复进行,直到不能再划分成子问题,或已经可以求解为止。这种自上而下将问题分解、求解,再自上而下引用、合并,求出最后解答的过程称为递归求解过程,这是一种分而治之的算法设计方法。
简单递归算法设计方法:

 

例题


有一个不带表头节点的单链表,其节点类型如下:
typedef struct NodeType{   ElemType data;   struct NodeType *next; }NodeType;
设计如下递归算法: 1   求以h为首指针的单链表的节点个数。 2   正向显示以h为首指针的单链表的所有节点值。 3   反向显示以h为首指针的单链表的所有节点值。 4   删除以h为首指针的单链表中值为x的第一个节点。 5   删除以h为首指针的单链表中值为x的所有节点。 6   输出以h为首指针的单链表中最大节点值。 7   输出以h为首指针的单链表中最小节点值。 8   删除并释放以h为首指针的单链表中所有节点。
解:设h为不带头节点的单链表(含n个节点),如图所示,h->next 也是一个不带头节点的单链表(含n-1个节点),两者除了相差一个节点外,其他都是相似的。

 


 


 1   求以h为首指针的单链表的节点个数。

 

设count(h)用于计算单链表h的结点个数,其递归模型如下:

对于的递归算法如下:

 

 

 

 

 

 

 

int count(NodeType *h){  if(h==NULL)    return 0;  else    return (1+count(h->next));}

 

 


 


 2   正向显示以h为首指针的单链表的所有节点值。

 

设traverse(h)用于正向扫描单链表h,其递归模型如下:

对于的递归算法如下:

 

 

 

 

 

 

 

 

void traverse(NodeType *h){  if(h!=null) {   printf("%d",h->data);   traverse(h->next);  }}

 

 


 


 3   反向显示以h为首指针的单链表的所有节点值。

 

设revtraverse(h)用于反向扫描链表h,其递归模型如下:

对于的递归算法如下:

 

 

 

 

 

 

 

 

void revtraverse(NodeType *h){  if(h!=null) {   revtraverse(h->next);   printf("%d",h->data);  }}

 

 


 


 4   删除以h为首指针的单链表中值为x的第一个节点。

 

设delnode(h,x)用于删除单链表h中第一个值为x的结点,其递归模型如下:


对于的递归算法如下:

 

void delnode(NodeType *&h,ElemType x){  NodeType *p;  if(h!=NULL) {   if(h->data == x)  {    p = h;    h = h->next;    free(p);   }   else    delnode(h->next,x);  }}

 

 


 


 5   删除以h为首指针的单链表中值为x的所有节点。

 

设delall(h,x)用于删除单链表h中所有值为x的结点,其递归模型如下:

对于的递归算法如下:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

void delall(NodeType *&h, ElemType x){  NodeType *p;  if(h!=NULL) {   if(h->data == x)  //若首结点的值为x  {    p = h;    h = h->next;    free(p);    delall(h,x);   //在后继结点递归删除   }   else              //若首结点值不为 x     delall(h->next,x);  //在后继结点递归删除   }}

 

 


 


 6   输出以h为首指针的单链表中最大节点值。

 

设maxv(h)用于计算单链表h的最大结点值,其递归模型如下(其中MAXV(x,y) 表示返回x和y的较大者):

对于的递归算法如下:

 

ElemType maxv(NodeType *h){  ElemType m;  if(h->next == NULL)    //只有一个结点的情况    return (h->data);  m = maxv(h->next);     //求后继结点的最大值    if(m>h->data)    return m;  else    return h->data;}

 

 


 


 7   输出以h为首指针的单链表中最小节点值。

 

设minv(h)用于计算单链表h的最小结点值,其递归模型如下(其中MIN(x,y)表示返回x和y的较小者):

对于的递归算法如下:

 

 

 

 

 

 

 

 

 

 

 

ElemType minv(NodeType *h){  ElemType m;  if(h->next == NULL)    return h->data;  m = minv(h->next);  if(m>h->data)    return h->data;  else    return m;}

 

 


 


 8   删除并释放以h为首指针的单链表中所有节点。

 

设release(h)的功能是删除并释放单链表h中所有结点,其递归模型如下:

对于的递归算法如下:

 

 

 

 

 

 

 

 

void release(NodeType *h){  if(h!=NULL) {  release(h->next);  free(h);  }}

 

 

 

标签:题型,单链,NodeType,递归,next,链表,节点,指针
From: https://www.cnblogs.com/3cH0-Nu1L/p/17909698.html

相关文章

  • 链表面试题解析
    链表面试题解析1.删除链表中=val的所有节点/***Definitionforsingly-linkedlist.*publicclassListNode{*intval;*ListNodenext;*ListNode(){}*ListNode(intval){this.val=val;}*ListNode(intval,ListNodenext){......
  • FreeRTOS--递归锁
    示例源码基于FreeRTOSV9.0.0递归锁1.概述递归锁是特殊的互斥量,允许同一任务多次获取和释放锁,而不会造成死锁;获取和释放的次数必须相同;递归锁的实现依赖于内部的uxRecursiveCallCount变量,它标记递归的次数,每次上锁加1,每次解锁减1,减为0才真正释放锁;递归锁也不能在中断内使用......
  • [LeetCode138-链表-中等] 复制带有随机指针的链表
    这道题是这样的,就是说有一个链表LindedNode,通常我们链表包含2个属性,一个是它的值val,另一个是它指向的下一个结点nextNode,但是这个题目中的链表还有一个属性,就是它还有个随机指针,这个随机指针可能指向链表中的任意结点(包括链表的结尾null结点,或者是自己)也就是说这个链表Lin......
  • 141.环形链表
    给你一个链表的头节点head,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。如果链表中存在环,则返回true。否则,返回false。示例输入:head=[3,2,0,-4];输出:true思路:循环遍历链表,检查是否存在重复的节点,可以使用......
  • 代码随想录算法训练营第四天 | 24. 两两交换链表中的节点,19.删除链表的倒数第N个节点,
    一、24.两两交换链表中的节点题目链接:LeetCode24.两两交换链表中的节点学习前:思路:未新增虚拟结点。节点数为0,1,2需要另外讨论。当节点数>=2时,返回的head值为第2个节点,需要3个指针first、second、prev,分别是第一个节点和第二个节点,以及第一个节点的前节点。while(first......
  • 142. 环形链表 II
    1.题目介绍给定一个链表的头节点 \(head\) ,返回链表开始入环的第一个节点。 如果链表无环,则返回 \(null\)。如果链表中有某个节点,可以通过连续跟踪\(next\)指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数\(pos\)来表示链表尾连接到链表中的......
  • Java-用递归的思想求斐波那契数列第n项的值
    一、思想-多路递归多路递归multirecursion就是在每次递归时包含多次(大于一次)的自身调用。也就是一个问题会被拆分成多个子问题。多路递归比单路递归在分析时间复杂度上比较复杂一些。二、斐波那契数列三、例子以n=4为例,当我们用下面(第四部分)的代码实现时,这个多路递归的求解过......
  • 142.环形链表II
    题目142.环形链表II要求给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中......
  • PTA|C语言|递归
    --------------------------------------------------------------------------------判断满足条件的三位数本题要求实现一个函数,统计给定区间内的三位数中有两位数字相同的完全平方数(如144、676)的个数。函数接口定义:intsearch(intn);其中传入的参数intn是一个三位数的正整数(......
  • 算法学习Day4两两交换,链表相交,环形链表
    Day4两两交换,链表相交,环形链表ByHQWQF2023/12/16笔记24.两两交换链表中的节点给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。解法:迭代法迭代法使用了虚拟头节点的技巧,迭代法代码class......