首页 > 技术文章 > 递归概述

tuyongjun 2022-04-27 00:15 原文

一、递归基本知识

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);
}

推荐阅读