递归概述

一、递归基本知识

1.定义

  • 递归(recursive invocation)指的是,一个函数不断引用自身,直到引用的唯一已知对象时止的过程

  • 在定义一个过程或函数,使用时调用自身。

  • 分类:直接递归、尾递归、其他递归

2.递归的情形

  1. 定义是递归的:例如数列
  2. 数据结构是递归的:例如不带头结点单链表。
  3. 问题的求解方法是递归的:例如Hanoi问题

3.递归模型

  • 递归模型(recursive model)是内生变量之间因果关系为单方向的结构方程模型。
fun(1)=1//递归体
fun(n)=n*fun(n-1)//递归出口
  • 递归思路:把一个不能或者不好直接及求解的大问题,转化成小问题。

  • 设计求解问题的递归模型

  1. 对原问题进行分析,假设出合理的小问题.
  2. 假设小问题是可解的。即给出大问题和小问题的关系-->递归体
  3. 确定一个特定的解-->递归出口

4.递归详解

(1)调用前

一个函数的运行期间调用另一个函数时,在运行被调用函数之前,系统需要完成3件事情:

(1)将所有的实参、返回地址等信息传递给被调用函数保存;

(2)为被调用函数的局部变量分配存储区;

(3)将控制转移到被调函数的入口。

(2)调用中

而从被调用函数返回调用函数之前,系统也应完成3件工作:

(1)保存被调函数的计算结果;

(2)释放被调函数的数据区;

(3)依照被调函数保存的返回地址将控制转移到调用函数。当有多个函数构成嵌套调用时,按照后调用先返回的原则。

(3)递归函数特点

所有递归函数的结构都是类似的。

(1)函数要直接或间接调用自身。

(2)要有递归终止条件检查,即递归终止的条件被满足后,则不再调用自身函数。

(3)如果不满足递归终止的条件,则调用涉及递归调用的表达式。在调用函数自身时,有关终止条件的参数要发生变化,而且需向递归终止的方向变化。

二、递归算法

1.示例一

用递归实现求数组A[0,1,2...n]的最小值

#include<stdio.h>
typedef int dataType;
float f(dataType A[],int i) {
dataType m;
if(i==0) return A[0];
else{m=f(A,i-1);
if(A[i]>m)
return A[i];
else
return m;
}
}
int main(){
dataType A[]={1,8,3,6,5};
int i=4;
int c=f(A,i);
printf("%d",c);
return 0;
}

2.示例二

递归输出单链表

#include <stdio.h>
#include <malloc.h>
typedef int DataType;
#define MaxLen 100;
typedef struct LinkNode
{
DataType data;
struct LinkNode *next;
} LinkList;
//初始化单链表
void InitList(LinkList *&L)
{
L=(LinkList *)malloc (sizeof(LinkList));
L->next=NULL;
}
//头插法
void CreateListF(LinkList *&L,DataType a[],int n)
{
LinkList *s;
int i;
InitList(L);
for(i=0;i<n;i++){
s=(LinkList *)malloc(sizeof(LinkList));
s->data=a[i];
s->next=L->next;
L->next=s;
}
}
//输出链表
void DispList(LinkList *L)
{
LinkList *p;
p=L->next;//指向第一元素;
if(p==NULL)
printf("List is Empty!\n");
else{
while(p!=NULL)
{
printf("%4d",p->data) ;
p=p->next;
}
printf("\n");
}
}
void traverse(LinkList *L){
if(L==NULL) return ;
printf("%4d",L->data);
traverse(L->next);
}
void traverseR(LinkList *L){
if(L==NULL) return ;
traverseR(L->next);
printf("%4d",L->data);
}
int main()
{
int a[]={1,2,3,4,5,6,7,8,9,10};
int n=10;
int i=6;
DataType e;
LinkList *L;
InitList(L);
CreateListR(L,a,n);
DispList(L);
printf("\n");
traverseR(L->next);
printf("\n");
printf("\n");
traverse(L->next);
}
posted @   涂勇军  阅读(210)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示