递归(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;
}
}
}