递归算法举例

文章包含多个编程示例,如使用递归计算阶乘、寻找数组最小值、顺序表中最大元素、释放单链表节点以及解决Hanoi问题的递归和非递归算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 求n!的递归算法

//求n!的递归算法
#include <stdio.h>
int fun(int n)
{
	if (n==1) 					//语句1
		return(1);				//语句2
	else 						//语句3
		return(fun(n-1)*n);		//语句4
}
int main()
{
	printf("10!=%d\n",fun(10));
	return 1;
}

求实数数组A[0..n-1]中的最小值

#include <stdio.h>
double Min(double A[],int i)
{	double min;
	if (i==0) return A[0];
	else
	{	min=Min(A,i-1);
		if (min>A[i]) return(A[i]);
		else return(min);
	}
}
int main()
{
	double a[]={9.2,5.5,3.8,7.1,6.5};
	int n=5;
	printf("Min=%lf\n",Min(a,4));
	return 1;
}

 求一个顺序表中最大元素。

//求一个顺序表中最大元素。
#include <stdio.h>
#define MaxSize 50
typedef int ElemType; 
typedef struct 
{	
	ElemType data[MaxSize];		//存放顺序表元素
   	int length;					//存放顺序表的长度
} SqList;						//顺序表的类型
ElemType Max(SqList L,int i,int j)  //求顺序表L中最大元素
{
	int mid;
	ElemType max,max1,max2;
	if (i==j) 
		max=L.data[i];				//递归出口
	else
	{	
		mid=(i+j)/2;
		max1=Max(L,i,mid);			//递归调用1
		max2=Max(L,mid+1,j); 		//递归调用2
		max=(max1>max2)?max1:max2;
	}
	return(max);
}
int main()
{
	int i;
	SqList L;
	ElemType a[]={3,1,5,8,0,2,4,7,9,6};
	for (i=0;i<10;i++)		//构造顺序表
		L.data[i]=a[i];
	L.length=10;
	printf("Max=%d\n",Max(L,0,9));
	return 1;
}

 释放一个不带头结点的单链表L中所有结点。

//单链表运算算法
#include <stdio.h>
#include <malloc.h>
typedef int ElemType;
typedef struct LNode  		//单链表结点类型
{
	ElemType data;
	struct LNode *next;		//指向后继结点
} LinkNode;
void CreateListF(LinkNode *&L,ElemType a[],int n)
//头插法建立单链表
{
	LinkNode *s;int i;
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next=NULL;
	for (i=0;i<n;i++)
	{	
		s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点
		s->data=a[i];
		s->next=L->next;			//将结点s插在原开始结点之前,头结点之后
		L->next=s;
	}
}
void CreateListR(LinkNode *&L,ElemType a[],int n)
//尾插法建立单链表
{
	LinkNode *s,*r;int i;
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next=NULL;
	r=L;							//r始终指向终端结点,开始时指向头结点
	for (i=0;i<n;i++)
	{	
		s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点
		s->data=a[i];
		r->next=s;					//将结点s插入结点r之后
		r=s;
	}
	r->next=NULL;					//尾结点next域置为NULL
}
void InitList(LinkNode *&L)
{
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next=NULL;
}
void DestroyList(LinkNode *&L)
{
	LinkNode *p=L,*q=p->next;
	while (q!=NULL)
	{	free(p);
		p=q;
		q=p->next;
	}
	free(p);						//此时q为NULL,p指向尾结点,释放它
}
bool ListEmpty(LinkNode *L)
{
	return(L->next==NULL);
}
int ListLength(LinkNode *L)
{
	LinkNode *p=L;int i=0;
	while (p->next!=NULL)
	{	i++;
		p=p->next;
	}
	return(i);
}
void DispList(LinkNode *L)
{
	LinkNode *p=L->next;
	while (p!=NULL)
	{	printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
}
bool GetElem(LinkNode *L,int i,ElemType &e)
{
	int j=0;
	LinkNode *p=L;
	while (j<i && p!=NULL)
	{	j++;
		p=p->next;
	}
	if (p==NULL)			//不存在第i个数据结点
		return false;
	else					//存在第i个数据结点
	{	e=p->data;
		return true;
	}
}
int LocateElem(LinkNode *L,ElemType e)
{
	LinkNode *p=L->next;
	int n=1;
	while (p!=NULL && p->data!=e)
	{	p=p->next;
		n++;
	}
	if (p==NULL)
		return(0);
	else
		return(n);
}
bool ListInsert(LinkNode *&L,int i,ElemType e)
{
	int j=0;
	LinkNode *p=L,*s;
	while (j<i-1 && p!=NULL)		//查找第i-1个结点p
	{	j++;
		p=p->next;
	}
	if (p==NULL)					//未找到位序为i-1的结点
		return false;
	else							//找到位序为i-1的结点p
	{	s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
		s->data=e;
		s->next=p->next;			//将结点s插入到结点p之后
		p->next=s;
		return true;
	}
}
bool ListDelete(LinkNode *&L,int i,ElemType &e)
{
	int j=0;
	LinkNode *p=L,*q;
	while (j<i-1 && p!=NULL)		//查找第i-1个结点
	{	j++;
		p=p->next;
	}
	if (p==NULL)					//未找到位序为i-1的结点
		return false;
	else							//找到位序为i-1的结点p
	{	q=p->next;					//q指向要删除的结点
		if (q==NULL) 
			return false;			//若不存在第i个结点,返回false
		e=q->data;
		p->next=q->next;			//从单链表中删除q结点
		free(q);					//释放q结点
		return true;
	}
}




//释放一个不带头结点的单链表L中所有结点。
#include "linklist.cpp"
void release(LinkNode *&L)
{
	if (L!=NULL)
	{
		release(L->next);
		free(L);
	}
}
int main()
{
	LinkNode *h;
	int a[]={1,2,3,4};
	InitList(h);		//h为带头结点的单链表
	ListInsert(h,1,1);
	ListInsert(h,2,2);
	ListInsert(h,3,3);
	ListInsert(h,4,4);
	printf("单链表:");
	DispList(h);
	printf("释放单链表\n");
	release(h->next);
	free(h);			//释放头结点
	return 1;
}

 递归算法求解从入口到出口的所有迷宫路径

//递归算法求解从入口到出口的所有迷宫路径
#include <stdio.h>
#define MaxSize 100
#define M 4
#define N 4
int mg[M+2][N+2]=
{ {1, 1, 1, 1, 1, 1},
  {1, 0, 0, 0, 1, 1},
  {1, 0, 1, 0, 0, 1},
  {1, 0, 0, 0, 1, 1},
  {1, 1, 0, 0, 0, 1},
  {1, 1, 1, 1, 1, 1}
};

typedef struct
{
	int i;				//当前方块的行号
	int j;				//当前方块的列号
} Box;
typedef struct
{
	Box data[MaxSize];
    int length;			//路径长度
} PathType;				//定义路径类型
int count=0;			//存放迷宫路径的条数
void mgpath(int xi,int yi,int xe,int ye,PathType path)
//求解路径为:(xi,yi)->(xe,ye)
{
	int di,k,i,j;
	if (xi==xe && yi==ye)		//找到了出口,输出路径
	{
		path.data[path.length].i = xi;
		path.data[path.length].j = yi;
		path.length++;
		printf("迷宫路径%d如下:\n",++count);
		for (k=0;k<path.length;k++)
			printf("\t(%d,%d)",path.data[k].i,path.data[k].j);
		printf("\n");
	}
	else						//(xi,yi)不是出口
	{
		if (mg[xi][yi]==0)		//(xi,yi)是一个可走方块
		{
			di=0;
			while (di<4)		//找(xi,yi)的一个相邻方块(i,j)
			{
				switch(di)
				{
				case 0:i=xi-1; j=yi;   break;
				case 1:i=xi;   j=yi+1; break;
				case 2:i=xi+1; j=yi;   break;
				case 3:i=xi;   j=yi-1; break;
				}
				path.data[path.length].i = xi;
				path.data[path.length].j = yi;
				path.length++;
				mg[xi][yi]=-1;			//避免重复找路径
				mgpath(i,j,xe,ye,path);
				path.length--;			//回退一个方块
				mg[xi][yi]=0;			//恢复(xi,yi)为可走
				di++;
			}
		}
	}
}
int main()
{
	PathType path;
	path.length=0;				//初始化路径长度
	mgpath(1,1,M,N,path);
	return 1;
}

求解Hanoi问题的递归和非递归算法 

//求解Hanoi问题的递归和非递归算法
#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
void Hanoi1(int n,char a,char b,char c)
{
	if (n==1) 
		printf("\t将第%d个盘片从%c移动到%c\n",n,a,c);
    else 
	{
		Hanoi1(n-1,a,c,b);
		printf("\t将第%d个盘片从%c移动到%c\n",n,a,c);
		Hanoi1(n-1,b,a,c);
	}
}

typedef struct
{	int n;							//盘片个数
	char x,y,z;						//3个塔座
	bool flag;						//可直接移动盘片时为true,否则为false
} ElemType;							//顺序栈中元素类型
typedef struct
{	ElemType data[MaxSize];			//存放元素
	int top;						//栈顶指针
} StackType;						//顺序栈类型

//--求解Hanoi问题对应顺序栈的基本运算算法--------------
void InitStack(StackType *&s)			//初始化栈
{	s=(StackType *)malloc(sizeof(StackType));
	s->top=-1;
}
void DestroyStack(StackType *&s)		//销毁栈
{
	free(s);
}
bool StackEmpty(StackType *s)			//判断栈是否为空
{
	return(s->top==-1);
}
bool Push(StackType *&s,ElemType e)		//进栈
{	if (s->top==MaxSize-1)
		return false;
	s->top++;
	s->data[s->top]=e;
	return true;
}
bool Pop(StackType *&s,ElemType &e)		//出栈
{	if (s->top==-1)
		return false;
	e=s->data[s->top];
	s->top--;
	return true;
}
bool GetTop(StackType *s,ElemType &e)		//取栈顶元素
{	if (s->top==-1)
		return false;
	e=s->data[s->top];
	return true;
}
//----------------------------------------------------
void Hanoi2(int n, char x, char y, char z)
{	StackType *st;							//定义顺序栈指针
	ElemType e,e1,e2,e3;
	if (n<=0) return;						//参数错误时直接返回
	InitStack(st);							//初始化栈
	e.n=n; e.x=x; e.y=y; e.z=z; e.flag=false;
	Push(st,e);								//元素e进栈
	while (!StackEmpty(st))					//栈不空循环
	{	Pop(st,e);							//出栈元素e
		if (e.flag==false)					//当不能直接移动盘片时
		{
			e1.n=e.n-1; e1.x=e.y; e1.y=e.x; e1.z=e.z;
			if (e1.n==1)					//只有一个盘片时可直接移动
				e1.flag=true;
			else							//有一个以上盘片时不能直接移动
				e1.flag=false;
			Push(st,e1);					//处理Hanoi(n-1,y,x,z)步骤
			e2.n=e.n; e2.x=e.x; e2.y=e.y; e2.z=e.z; e2.flag=true;
			Push(st,e2);					//处理move(n,x,z)步骤
			e3.n=e.n-1; e3.x=e.x; e3.y=e.z; e3.z=e.y;
			if (e3.n==1)					//只有一个盘片时可直接移动
				e3.flag=true;
			else
				e3.flag=false;				//有一个以上盘片时不能直接移动
			Push(st,e3);					//处理Hanoi(n-1,x,z,y)步骤
		}
		else								//当可以直接移动时
			printf("\t将第%d个盘片从%c移动到%c\n",e.n,e.x,e.z);
	}
	DestroyStack(st);						//销毁栈
}

int main()
{
	int n=3;
	printf("递归算法:%d个盘片移动过程:\n",n);
	Hanoi1(n,'X','Y','Z');
	printf("非递归算法:%d个盘片移动过程:\n",n);
	Hanoi2(n,'X','Y','Z');
	return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿隆要成大牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值