《算法笔记》第4章 入门篇(2)---算法初步 4.3递归

4.3.2 递归(很适合实现分治的思想):

递归的两个重要概念:
      1.递归式:将原问题分解为若干个子问题的手段
      2.递归边界:分解的尽头

1.递归实现n!

在这里插入图片描述

#include<iostream>
using namespace std;
int Fun(int n)
{
    if(n==0 || n==1)
        return 1;
    else
        return Fun(n-1)+Fun(n-2);
}
int main()
{
    int a;
    cin >> a;
    cout << Fun(a);
}


2.递归实现Fibonacci函数:

在这里插入图片描述

3.递归实现全排列:

在这里插入图片描述

#include<iostream>
using namespace std;
const int maxn=100;
int n,p[maxn],HashTable[maxn]={false};  //散列数组HashTable的目的是为了保证没有重复的输出。p数组表示当前排列的元素
void generateP(int index)      //index表示当前的位置
{
    //递归边界:
    if(index==n+1)
    {
        for(int i=1; i<=n; i++)
            cout << p[i];
        cout << endl;
        return ;
    }
    //递归式子:
    for(int x=1; x<=n; x++)   //x表示遍历n中每一个数
    {
        if(HashTable[x]==false)   //表示x在之前还没有被输出
            {
                HashTable[x]=true;      //立即标记x已经被输出了
                p[index]=x;         //将x放到对应的位置
                generateP(index+1);      //赶紧进入下一个位置的数字输入
                HashTable[x]=false;    //当此函数调用回来时,要把之前的数字的标记全部清除以重新排列
            }
    }
}
int main()
{
    n=4;
    generateP(1);
}


4.n皇后问题:

1.什么是n皇后问题:

在这里插入图片描述

对于他妈的n皇后问题,就是在不同行不同列上去放皇后,并且保证皇后不在同一条对角线上。首先就是先保证不在同一行同一列,按照下面所讲的那个数字串,就是24135,,就是表示第1列中的皇后在第2行,第2列中的皇后在第4行,第3列中皇后在第1行…就相当于对这5个数进行全排列,如果说某一行上有两个皇后那么这5个数字就会有重复的显然不是全排列的结果,所以n皇后的问题就是先全排列再判断一条对角线上是否有2个及以上皇后,是的话即为abs(i-j)==abs(p[i]-p[j])

具体思路(暴力法):

在这里插入图片描述

int count=0;
void generateP(int index)
{
    if(index==n+1)
    {
        bool flag=true;       //先设置flag为true,
        for(int i=1; i<=n; i++)  //双层for判断是否有皇后在同一条对角线上,若是则设置flag为false
            for(int j=1; j<=n; j++)
                if(abs(i-j)==abs(p[i]-p[j]))
                    flag=false;
    }
    if(flag)     //当双层for循环完后,如果flag仍为true,则count++
        count++;
    return ;    //返回空
    for(int x=1; x<=n; x++)
    {
        if(HashTable[x]==false)  //这些都是全排列的代码,不变
        {
            p[index]=x;
            HashTable[x]=true;
            generateP(index+1);
            HashTable[x]=false;
        }
    }
}

具体思路(回溯法):

在这里插入图片描述

回溯法定义:
在这里插入图片描述

int count=0;
void generateP(int index)
{
    if(index==n+1)
    {
        count++;
        return ;
    }
    for(int x=1; x<=n; x++)
    {
        if(HashTable[x]==false) //这个x为啥表示行?因为在全排列时这些数字就是表示皇后所在的行
        {
            //下面8行代码是在原来的全排列基础上新增的,作用:在决定每个位置放数字之前就进行一次判断
            //先设置flag为true,然后让pre从1开始到index之前,判断有没有在同一个对角线上的
            bool flag=true;
            for(int pre=1; pre<index; pre++)  //index表示要往当前位置插入数字,在插入之前进行判断
                if(abs(index-pre)==abs(x-p[pre]))
                {
                    flag=false;
                    break;
                }   
            if(flag==true)
            {
                p[index]=x;
                HashTable[x]=true;
                generateP(index+1);
                HashTable[x]=false;
            }                
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值