算法设计与分析(第三节课——递归算法)

一、递归法的处理过程

  1. 将f(n)向f(n-1)转化,f(n-1)向法f(n-2)转化,直到f(0)
  2. 反向由f(1)一直推出f(n)
#include<stdio.h>

void fun(int n)
{
	if(n<1)
	   return ;
	else
	   {
	   	printf("调用f(%d)前,n=%d\n",n-1,n);
	   	fun (n-1); 
	   	printf("调用f(%d)后,n=%d\n",n-1,n);
	   }
}

int main()
{
	int n;
	printf("请输入一个整数值");
    scanf("%d",&n);
	fun(n);	
}

2.运行结果
在这里插入图片描述

二、递归法和非递归法求n的阶层

  1. 非递归法
#include<stdio.h>

int fun(int n)
{
	int f=1,i;
	for(i=2;i<=n;i++)
	   f=f*i;
	return f;
}

int main()
{
	int n;
	printf("请您输入求阶层的数");
	scanf("%d",&n);
	printf("%d!=%d",n,fun(n)); 
 } 
  1. 递归法
#include<stdio.h>

int fun(int n)    
{
   if(n==1)	
	  return 1;
	else
	  return(fun(n-1)*n);   //fun(n)=n*fun(n-1)=n*n-1*fun(n-2)*...* fun(1)
}

int main(){
	int n;
	printf("输入要求阶层的数");
	scanf("%d",&n);
	printf("%d!=%d",n,fun(n));
} 

三、Fibonacci数列
数列: 0,1,1,2,3,5,8,13,21,34,55, 89,144,233,377,610,987,1597,2584, 4181,6765,10946,17711,28657,46368

a1=1,a2=1
an=a(n-1)+a(n-2)

  1. 非递归法
#include<stdio.h> 
int f(int n)
{
	int i,f1,f2,f3;
	if(n==1||n==2)
	   return(1);
	f1=1,f2=1;  //如果输入的值为1或者2,直接输出 
	for(i=3;i<=n;i++) //从3开始,进行循环   
	{
		f3=f1+f2;  //先计算f3            f1+f2=f3 
		f1=f2;                     //       f1+f2=f3   判断是否满足循环条件 
		f2=f3;                    //           f1+f2=f3
    }    
	return(f3);
 } 
 
int main()
{
	int n;
	printf("请输入要求斐波拉数列的项数");
	scanf("%d",&n);
	printf("f(%d)=%d",n,f(n));
}
  1. 递归法
#include<stdio.h>

int f(int n)
{
	if(n==1||n==2)	
	   return 1;
	else
	   return f(n-1)+f(n-2); 
}

int main()
{
	int n;
	printf("请输入要求数列的下标");
	scanf("%d",&n);
	printf("f(%d)的值为%d",n,f(n)); 
}

四、分解一个高位数

  1. 代码
#include<stdio.h>

void digits(int n)
{
	if(n!=0)   //如果n不为0,让n的值一直除以10,直到n=0。说明此事n已经是最高位的数值 
	{
		digits(n/10);
		printf("%d\n",n%10); //最后一次输出最高位,退出回到上一层有两位数,对两位数进行操作取个位 
	}	
 } 
 
 int main()
 {
 	int n;
 	printf("请输入一个数字");
 	scanf("%d",&n);
 	digits(n);
 }
  1. 运行结果
    在这里插入图片描述

五、冒泡安排的递归算法

  1. 图解在这里插入图片描述
  2. 代码
#include<stdio.h>

void swap(int *a,int *b) //交换函数
{
	int t;
	t=*a;
	*a=*b;
	*b=t;
 } 

void BubbleSort(int a[],int n,int i)
{
	int j;
	bool exchange; //确认已经排好的序 
	if(i==n-1)  //当i等于n-1时,表示已经达到最后一个数 
	  return ;
    else
    {
       exchange=false;	  
       for(j=n-1;j>i;j--) //从最后一个数开始一直到第一个数 
    	if(a[j]<a[j-1])   //相邻的两个数进行判,将较大的值放在后面,每一轮炸出较小的值放在前面 
		{
    		swap(&a[j],&a[j-1]); 
    		exchange=true;  
		}
       if(exchange==false)  //如果没有发生交换,证明已经排好序 
         return ;
        else
           BubbleSort(a,n,i+1); //排除最前的i个已经排好的数,往前移动 
	}
 } 
 
 int main()
 {
    int i;
 	int  a[]={3,2,4,6,1,2,4};
 	printf("排序前,数组为");
 	for(i=0;i<7;i++)
 		printf("%d ",a[i]);
 	printf("\n"); 
 	BubbleSort(a,7,0);
 	printf("排序后,数组为");
 	for(i=0;i<7;i++)
 		printf("%d ",a[i]);
    return 0;
 }
 

3.运行结果
在这里插入图片描述

六、选择排序的递归算法

  1. 图解
    在这里插入图片描述
  2. 代码
#include<stdio.h>
void swap(int *a,int *b)
{
	int t;
	t=*a;
	*a=*b;
	*b=t;
 } 


void SelectSort(int a[],int n,int i)
{
	int j,k;     
	if(i==n-1)  //表示已经选择到最后一个值,无序排序
	  return ;
	else
	{
		k=i;   //i后面的数与i依次比较大小,将最小的数放到a[i]的位置 
		for(j=i+1;j<n;j++)//循环比较 
	      if(a[j]<a[k]) //将较小的数用k临时存储 
		      k=j;          
		if(k!=i)     //如皋存在比a[k]更小的值,发生交换 
		   swap(&a[i],&a[k]);//注意使用交换函数时,只有传入地址才能改变对应的值 
		//a[i]-------- a[k]-----a[j]
	    //赋值        可变      不可变 
		SelectSort(a,n,i+1);//递归分配下一个位置,a[i+1]下一个空间 
	}	
 } 
 
 
 int main()
 {
 	int i;
 	int  a[]={3,2,4,6,1,2,4};
 	printf("排序前,数组为");
 	for(i=0;i<7;i++)
 		printf("%d ",a[i]);
 	printf("\n"); 
 	SelectSort(a,7,0);
 	printf("排序后,数组为");
 	for(i=0;i<7;i++)
 		printf("%d ",a[i]);
    return 0;
 }
  1. 运行结果
    在这里插入图片描述

七、递归求罗汉塔

  1. 解题

    1. 目标:将n个积木从x移到z上
    2. 解题思路:
      1. 第n-1个 从x移到y
      2. 第n个 从x移到z
      3. 第n-1个 从y移到z
      4. 递归操作以上步骤
  2. 代码

#include<stdio.h>

void f(int n ,char x,char y,char z)
{
	if(n==1)//如果等于1,直接从a到c,直接搬过去 
	   printf("将盘片%d从%c搬到%c\n",n,x,z);
	else
	{
	  	 f(n-1,x,z,y);//将上方的数由x移到y 
	  	 printf("将盘片%d从%c搬到%c\n",n,x,z);//将n从x移到z 
	  	 f(n-1,y,x,z);//将y移到x 
	}
	//基本解题思路 
	//第n-1个  从x移到y 
	//第n个    从x移到z
	//第n-1个  从y移到z 
}

int main()
{   
    int n;
    char a='a';
	char b='b';
	char c='c'; 
	printf("请输入汉罗塔的层数");
	scanf("%d",&n);
	f(n,a,b,c);
}

3.结果
在这里插入图片描述
八、六皇后问题递归解法

  1. 解题思路
    1. 递归思想:每行放置一个皇后
    2. 限制:每个皇后不能是同行,同列,对角线关系

1.代码

#include<stdio.h>
#include<math.h> 
int q[7]={0};
int p[7][7]={0};
int k=0;
int t=1; 

bool place(int i,int j) //传入两个参数 
{
	if(i==1)    //第一行的数,可以不需要进行判断 
	  return true;  
	int k=1;    
	while(k<i)//判断已经加入数列q[k]中的每一个皇后与将要放置皇后的关系 
	{
		if(q[k]==j||(abs(q[k]-j)==abs(i-k)))//要放置皇后的列已经不相同,现在要保证行数不同,和不在同一条对角线上 
		   return false;   
		k++;//判断下一个已经放置好的皇后 
		}	
	return true;//通过返回 
 } 
 
 
 void show(int p[7])     //打印一维存放方式 
{	
	 for(int i=1;i<=6;i++)
	 {
 	     printf("%d ",p[i]);
     }
     printf("\n");
 } 
 
  
 void show1(int p[][7])   //打应棋盘 
{	
	 for(int i=1;i<=6;i++)
   {   
	  for(int j=1;j<=6;j++)
	 {
 	     printf("%d ",p[i][j]);
     }
     printf("\n");
   }
 } 
 
 
 void queen(int i,int n) //i为函数, 
 {
 	if(i>n)
 	  return ;
 	else
 	{
 	   for(int j=1;j<=n;j++)  //从第一列开始 
 		{
		 if(place(i,j))        //判断是否可以放置 
 	   	{
 		   q[i]=j;	     //将列赋给对应的行  
 		   queen(i+1,n);      //放置下一个点 
 		   
 		   if(i==6)//如果i=6说明已经摆好了皇后 
	       {
	       	printf("解法%d\n",t++);
			show(q);                //展示数列 
			for(int i=0;i<=6;i++)  //打印相应的棋盘 
	           p[i][q[i]]=1;       
	        printf("\n");
	        show1(p);
	      	for(int i=0;i<=6;i++)
	           p[i][q[i]]=0;
	        printf("\n");
	       }
		 }
      	}
	 }	
 }
 
 int main()
 {
 	queen(1,6);
 }

2.结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值