链表递归题型

发布时间 2023-12-17 20:15:16作者: 3cH0_Nu1L

递归的定义

  在定义一个过程或函数时出现调用本过程或本函数的成分,称之为递归。若调用自身,称之为直接递归。若过程或函数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);  }}