递归

递归(recursion):一个直接调用自己或通过一系列调用语句间接调用自己。对问题进行分解、求解的过程得到的是和原问题性质相同的子问题,由此自然得到一个递归算法,且比利用“栈”实现的非递归算法跟符合人们的思维逻辑。利用分治法(divide and conquer)进行递归算法设计:写出递归定义:基本项和归纳项。基本项:描述了一个或几个递归过程的终结状态(不需要递归可以直接求解的状态)。归纳项:描述了如何从当前状态到终结状态的转化。递归设计的实质:当一个复杂的问题可以分解成若干子问题来处理,其中某些子问题与原问题有相同的特征属性,则可以利用和原问题相同的分析处理方法;反之,子问题解决了,原问题就迎刃而解了。如二叉树、广义表等本身结构固有的递归特性,则它们的操作可以用递归地描述;还有Fibonacci数列、Hanoi塔、八皇后问题等。
1.在运行被调函数之前系统需要完成3件事:1)将所有的实在参数、返回地址等信息传递给被调用函数保存;2)为被调函数的局部变量分配存储区;3)将控制转移到被调函数的入口。2.被调函数返回调用函数之前系统也要完成3件事:1)保存被调函数的结果;2)释放被调函数的数据区;3)依照被调函数保存的返回地址将控制转移到调用函数。3.八皇后(eight queens):如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4 时问题有解。利用:试探和回溯法(backtracking)求解时,描述求解过程的状态不是一颗满多叉树。求解过程可以看成是在约束条件下进行先序遍历,并在遍历过程中剪去那些不满足条件的分支。


#include<iostream>
#include<stack>

using namespace std;

/*
*fibonacci
*函数功能:fibonacci数列被递归定义:F0=0,F1=1,Fn=F(n-1)+F(n-2);(n>=2)
*输入:第n项
*返回值:fibonacci数列的第n项
*/
int fibonacci(int n){
    if (n == 0 || n == 1)
        return n;
    else
        return fibonacci(n-1) + fibonacci(n-2);
}
/*
*hanoi
*函数功能:将分别命名X、Y、Z的塔,将X轴上的n个圆盘移至塔座Z上
*输入:n圆盘个数;X将要移动圆盘塔;Y辅助塔;Z圆盘要移动到的塔
*返回值:void
*/
void move(char X, int n, char Z){  //将编号为n的圆盘从X移到Z
    cout << " Move disk " << n << " from " << X << " to " << Z << endl;
}
void hanoi(int n, char X, char Y, char Z){
    if (n == 1)
        move(X,1,Z);
    else{
        hanoi(n - 1, X, Z, Y); //将编号为n的圆盘之上的n-1个圆盘从X塔移至Y塔上
        move(X, n, Z);
        hanoi(n - 1, Y, X, Z); //将Y塔上的n-1圆盘移至Z塔上
    }
}
/*
*eightQueue
*函数功能:回溯法求8皇后的解数,并打印出来
*输入:i为从第i行起为后续棋子选择合适位置;n为n*n的棋盘
*返回值:void
*/
static int eightQueens[8] = { 0 }; //eightQueens[n]表示为第n行第eightQueens[n]列存在皇后
static int cnt = 0; //合法布局的种数
int isSafe(int row, int column){ //检查是否存在多个皇后在同一行/列/对角线情况
    for (int i = 0; i < row; i++){
        if (eightQueens[i] == column) //多个皇后是否在同一列
            return 0;
        if ((i - eightQueens[i]) == (row - column)) //多个皇后是否在主对角线上
            return 0;
        if ((i + eightQueens[i]) == (row + column)) //多个皇后是否在次对角线上
            return 0;
    }
    return 1;
}
void print(){ //打印
    for (int i = 0; i < 8; i++){
        for (int j = 0; j < 8; j++){
            if (j == eightQueens[i])
                cout << "#";
            else
                cout << "*";
        }
        cout << endl;
    }
    cout << "==========================\n";
}
void eightQueen(int i, int n){
    for (int j = 0; j < n; j++){
        if (isSafe(i, j)){
            eightQueens[i] = j;
            if (i==n-1){
                cnt++;
                print();
                eightQueens[i] = 0;
                return;
            }
            eightQueen(i + 1, n);
            eightQueens[i] = 0;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值