递归与分治

PS:据说二分法天下第一?

递归

认识斐波那契数列:
F(0)=0,F(1)=1,当 n>1时,F(n)=F(n-1)+F(n-2);

迭代方法
#include "stdio.h"

int main()
{
	int i ;
	int a[40];
	
	a[0] = 0;
	a[1] = 1;
	printf("%d %d ",a[0],a[1]);
	for(i=2;i<40;i++)
	{
		a[i]=a[i-1]+a[i-2];
		printf("%d ",a[i]);
	}

return 0;
}

递归方法
int fib(int i);

int main(void)
{
	int i = 39;
	int a[40];
	while(i != -1)
	{
        printf("%d ",fib(i));
        i--;
	}
	return 0;
}

int fib(int i)
{
	if(i<2)
	{return i == 0 ? 0:1;}
	return fib(i-1)+fib(i-2);
}

  递归和迭代的区别是:递归用的选择结构,迭代用的循环结构。
  使用递归让程序更清晰,更易维护;但是递归相较于迭代来说也会消耗更多的时间和内存。
  递归函数执行分为调用和回退阶段,递归的回退顺序是它调用顺序的逆序。每个递归定义必须至少有一个条件,当满足这个条件时递归不再进行,即函数不再调用自身而是返回值。

   经典八皇后问题
#include "stdio.h"

count = 0;
int NotDanger( int row, int j, int (*chess)[8] )
{
    int i, k, flag1=0, flag2=0, flag3=0;

    //i=行,k=列
      for( i=0; i < 8; i++ )
      {
    		if( *(*(chess+i)+j) != 0 )//列
       		{
          		flag1 = 1;
          		break ;
      		}
    }
    for(i=row, k=j; i>=0 && k>=0; i--, k-- )//左上方
    {
        if(*(*(chess+i)+k) != 0)
        {
            flag2 = 1;
            break ;
        }
    }
    for(i = row,k = j;i >= 0 && k < 8;i--,k++)//右上方
    {
        if(*(*(chess+i)+k) != 0)
        {
            flag3 = 1;
            break ;
        }
    }
    if(flag3 || flag2 || flag1)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

// 参数row: 表示起始行
// 参数n: 表示列数
// 参数(*chess)[8]: 表示指向棋盘每一行的指针
void EightQueen( int row, int n, int (*chess)[8] )
{
        int chess2[8][8], i, j;

        for( i=0; i < 8; i++ )
        {
                for( j=0; j < 8; j++ )
                {
                        chess2[i][j] = chess[i][j];
                }
        }

        if( 8 == row )
        {
                printf("第 %d 种\n", count+1);
                for( i=0; i < 8; i++ )
                {
                        for( j=0; j < 8; j++ )
                        {
                                printf("%d ", *(*(chess2+i)+j));
                        }
                        printf("\n");
                }
                printf("\n");
                count++;
        }
        else
        {
                for( j=0; j < n; j++ )
                {
                        if( NotDanger( row, j, chess ) ) // 判断是否危险
                        {
                                for( i=0; i < 8; i++ )
                                {
                                        *(*(chess2+row)+i) = 0;
                                }

                                *(*(chess2+row)+j) = 1;

                                EightQueen( row+1, n, chess2 );
                        }
                }
        }
}

int main()
{
        int chess[8][8], i, j;

        for( i=0; i < 8; i++ )
        {
                for( j=0; j < 8; j++ )
                {
                        chess[i][j] = 0;
                }
        }

        EightQueen( 0, 8, chess );

        printf("总共有 %d 种解决方法!\n\n", count);

        return 0;
}


分治

  用递归方法实现二分。

#include "stdio.h"

#define Size 10

typedef int ElemType;
int refind(ElemType *data,int begin,int end,ElemType num);

int main(void){
            ElemType data[Size]={10,20,30,40,50,60,70,80,90,100};
            ElemType num;
            for(int i = 0;i<Size;i++)
                    printf("%d ",data[i]);
            printf("\n请输入要查找的数据:\n");
            scanf("%d",&num);
            int flag = refind(data,0,9,num);
            printf("位置为:%d\n",flag+1);
            return 0;
}

int refind(ElemType *data,int begin,int end,ElemType num)
{
    int mid;
    if(begin > end)
    {
        return -1;
    }
    else
    {
        mid = (begin + end)/2;
        if(data[mid] == num)
        {
            return (mid);
        }
        if(num > data[mid])
        {
            return refind(data, mid+1, end, num);
        }else
        {
            return refind(data, begin, mid-1, num);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值