递归的定义
在定义一个过程或函数时出现调用本过程或本函数的成分,称之为递归。若调用自身,称之为直接递归。若过程或函数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个节点),两者除了相差一个节点外,其他都是相似的。
01
1 求以h为首指针的单链表的节点个数。 设count(h)用于计算单链表h的结点个数,其递归模型如下: 对于的递归算法如下:int count(NodeType *h)
{
if(h==NULL)
return 0;
else
return (1+count(h->next));
}
02
2 正向显示以h为首指针的单链表的所有节点值。 设traverse(h)用于正向扫描单链表h,其递归模型如下: 对于的递归算法如下:void traverse(NodeType *h)
{
if(h!=null)
{
printf("%d",h->data);
traverse(h->next);
}
}
03
3 反向显示以h为首指针的单链表的所有节点值。 设revtraverse(h)用于反向扫描链表h,其递归模型如下: 对于的递归算法如下:void revtraverse(NodeType *h)
{
if(h!=null)
{
revtraverse(h->next);
printf("%d",h->data);
}
}
04
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);
}
}
05
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); //在后继结点递归删除
}
}
06
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;
}
07
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;
}
08
8 删除并释放以h为首指针的单链表中所有节点。 设release(h)的功能是删除并释放单链表h中所有结点,其递归模型如下: 对于的递归算法如下:void release(NodeType *h)
{
if(h!=NULL)
{
release(h->next);
free(h);
}
}
真题回顾
已知f为单链表的表头指针,链表中存储的都是整型数据,请写出实现下列运算的递归算法,求: (1)链表中最大整数; (2)所有整数的平均值。(10分)