算法分析 递归与分治

1.  Fibonacci数列

   无穷数列1,1,2,3,5,8,13,21,34,55,……,称为Fibonacci数列。它可以递归地定义为:

《算法分析 递归与分治》

第n个Fibonacci数可递归地计算如下:

int fibonacci(int n)

   {

       if (n <= 1) return 1;

       return fibonacci(n-1)+fibonacci(n-2);

   }

  1. 编写完整的主函数,分别记录利用上述递归函数求第45,46,47,48个Fibonacci数所花费的时间。
#include<stdio.h>

#include<time.h>

long fibonacci(int n)

{

       if (n <= 1)

                 return 1;

       return fibonacci(n-1)+fibonacci(n-2);

}

void main()

{

  int N,i;

  double s;

  clock_t start , stop;

  for(i=45;i<=48;i++){

  start=clock();

  fibonacci(i);

  printf("第%d个运行时间",i);

  stop=clock();

   s=(stop-start)/CLK_TCK;

  printf(" %lfs\n",s);

  }

}

《算法分析 递归与分治》

(2)将递归函数改为尾递归,或者是递推函数,求第45,46,47,48个Fibonacci数所花费的时间,观察效率是否得到提高。

#include<stdio.h>
#include<time.h>
long tailfib(int n,int acc1,int acc2) {
    if (n < 2) {
        return acc1;
    }
     
    return tailfib(n-1,acc2,acc1 + acc2);
}
void main()
{
  int N,i;
  double s;
  clock_t start , stop;
  for(i=45;i<=48;i++){
  start=clock();
  printf("%d:%lld",i,tailfib(i,1,1));
  stop=clock();
   s=(stop-start)/CLK_TCK;
  printf(" %lfs\n",s);
  }
}

《算法分析 递归与分治》

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
 
int a[100];
int n;
 
int max;   //当前最大元素 
int f(int n)  
{
	int min;   //当前最小元素 
	if(n==2)     //只有两个元素时,直接求解(最小问题) 
	{
		if(a[n-2]>a[n-1]){
			max=a[n-2],min=a[n-1];
		}
		else{
			max=a[n-1],min=a[n-2]; 
		}
		return min;
	}
	else
	{ 
		min=f(n-1);		//递归找第二大元素 
		if(a[n-1]>max){ 
			min=max,max=a[n-1];   //找到前面n-1个元素中最大和第二大元素时
		}
		if(a[n-1]<max&&a[n-1]>min){
			min=a[n-1]; //再与第n个元素比较找第二大元素 
		}
		return min;   //返回结果 
	}
}
 
void random() 
{
	srand(time(NULL));
	for(int i=0;i<n;i++)
	{
		a[i]=1+rand()%100;
	}
}
 
int main()
{
	
	int s;
	printf("请输入元素的个数n:");
	scanf("%d",&n);
	random();
	printf("\n这n个数依次为: ");
	for(int j=0;j<n;j++)
		printf("%d\t",a[j]);
	s=f(n);
	printf("\n\n这n个数中第二大元素为:%d\n",s);
	return 0;
}

《算法分析 递归与分治》

5. 棋盘覆盖问题

   在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。

算法描述如下:

参数说明:

子棋盘:由棋盘左上角的坐标tr,tc和棋盘大小size表示。

特殊方格:在二维数组中的坐标位置是(dr,dc)。

#include<stdio.h>
int Martrix[100][100];
int tile=0;   //整形变量,记录L型骨牌的数量
void chessBoard(int tr, int tc, int dr, int dc, int size) //tr和tc分别是棋盘左上角方格的行号,列号; dr和dc分别代表特殊方格的行号,列号
{
    int s,t;
    if (1 == size) return;

    s = size/2; //分割棋盘
    t = ++ tile; //L型骨牌号,初始值为0


    if (dr < tr + s && dc < tc +s)  //用L型骨牌号覆盖左上角子棋盘
    {
        chessBoard(tr,tc,dr,dc,s);//特殊方格在此棋盘中
    }
    else //特殊方格不在此棋盘中用,t号L型骨牌覆盖右下角
    {
        Martrix[tr+s-1][tc+s-1] = t;   //覆盖本子棋盘中的其余方格
        chessBoard(tr,tc,tr+s-1,tc+s-1,s);
    }

    if (dr < tr + s && dc >= tc + s )  //用L型骨牌号覆盖右上角子棋盘
    {
        chessBoard(tr,tc+s,dr,dc,s); //特殊方格在此棋盘中
    }
    else //特殊方格不在此棋盘中用,t号L型骨牌覆盖左下角
    {
        Martrix[tr+s-1][tc+s] = t; //覆盖本子棋盘中的其余方格
        chessBoard(tr,tc+s,tr+s-1,tc+s,s);
    }

    if (dr >= tr + s && dc < tc + s) //用L型骨牌号覆盖右上角棋盘
    {
        chessBoard(tr+s,tc,dr,dc,s); //特殊方格在此棋盘中
    } 
    else  //特殊方格不在此棋盘中,用t号L型骨牌覆盖左下角
    {
        Martrix[tr+s][tc+s-1] = t;  //覆盖本子棋盘中的其余方格
        chessBoard(tr+s,tc,tr+s,tc+s-1,s);
    }

    if (dr >= tr + s && dc >= tc + s)  //用L型骨牌号覆盖右上角子棋盘
    {
        chessBoard(tr+s,tc+s,dr,dc,s); //特殊方格在此棋盘中
    } 
    else   //特殊方格不在此棋盘中用t号L型骨牌左上角
    {
        Martrix[tr+s][tc+s] = t;  //覆盖本子棋盘中的其余方格
        chessBoard(tr+s,tc+s,tr+s,tc+s,s);
    }

}

int main()
{
    int size,r,c,row,col;
     printf("设置棋盘大小:");
    scanf("%d",&size);
	printf("\n输入特殊方格位置:(x,y)  ");
    scanf("%d%d",&row,&col);
    chessBoard(0,0,row,col,size);

    for (r = 0; r < size; r++)
    {
        for (c = 0;c<size; c++)
        {
            printf("%2d ",Martrix[r][c]);
        }
        printf("\n");
    }

    return 0;
}

《算法分析 递归与分治》

 

 

    原文作者:递归与分治算法
    原文地址: https://blog.csdn.net/qq_41398448/article/details/83042910
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞