九、递归和分治思想
来源:互联网 发布:义乌淘宝村 编辑:程序博客网 时间:2024/06/05 16:53
递归定义
在高级语言中,函数调用自己和调用其他函数并没有本质的不同,我们把一个直接调用自己或通过一系列的调用语句简介地调用自己的函数,称为递归函数。不过,每个递归定义必须至少有一个条件,当满足这个条件是递归不再进行,即函数不再调用自身而是返回。
经典递归问题:汉诺塔
问题描述:
有一个梵塔,塔内有三个座A、B、C,A座上有诺干个盘子,盘子大小不等,大的在下,小的在上(如图)。
把这些个盘子从A座移到C座,中间可以借用B座但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。
描述简化:把A柱上的n个盘子移动到C柱,其中可以借用B柱。
算法讨论:
定义函数move(n,x,y,z)表示把x上的n个盘子移动到z上,y为中间临时量
printf(x,z)表示把x上的盘子移到z上
最初需要解决的状态为:move(n,x,y,z)
状态1:先把x上的n-1个盘子移动到y上(暂时当做整体来看)
move(n-1,x,z,y)
中间状态:把x上剩的大盘子移动到z上
printf(x,z)
状态2:此时把y上的n-1个盘子移动到z上(操作结束后回到状态1)
move(n-1,y,x,z)
#include <stdio.h>//将n个盘子从x借助y移动到z void move(int n,char x,char y,char z){ if(1==n) { printf("%c-->%c\n",x,z); } else { move(n-1,x,z,y);//将n-1个盘子借助z移动到y上 printf("%c-->%c\n",x,z);//将第n个盘子从x移动到z上 move(n-1,y,x,z); //将n-1个盘子从y借助x移到z上 }} int main(){ int n; printf("请输入汉诺塔的层数:"); scanf("%d",&n); printf("移动的步骤如下:\n"); move(n,'X','Y','Z'); return 0;}
八皇后问题
在8x8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
递归算法:
#include <stdio.h>int count=0;//判断是否危险,即行,列,斜线是否有棋子 int notDanger(int row,int j,int (*chess)[8]){ int i,k,flag1=0,flag2=0,flag3=0,flag4=0,flag5=0; //判断列方向 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<8&&k>=0;i++,k--) { if(*(*(chess+i)+k)!=0) { flag3=1; break; } } //判断右上方 for(i=row,k=j;i>=0&&k<8;i--,k++) { if(*(*(chess+i)+k)!=0) { flag4=1; break; } } //判断右下方 for(i=row,k=j;i<8&&k<8;i++,k++) { if(*(*(chess+i)+k)!=0) { flag5=1; break; } } if(flag1||flag2||flag3||flag4||flag5) { return 0; } else { return 1; }}//row 表示初始行数,n表示列数,int (*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)//表示进行到第8行已经成功 { printf("第 % d 种",count+1); printf("\n"); 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;//把棋盘置为0 } *(*(chess2+row)+j)=1;//不危险的位置存放1 EightQueen(row+1,n,chess2); } } } }int main(){ int chess[8][8],i,j; for(int i=0;i<8;i++) { for(int j=0;j<8;j++) { chess[i][j]=0; } } EightQueen(0,8,chess); printf("总共有 %d 种解决方法!\n\n",count); return 0;}
0 0
- 九、递归和分治思想
- 递归和分治思想 (上)
- 专注于<递归算法和分治思想>
- 学习笔记之递归和分治思想
- 快速排序 : 分治和递归思想
- 递归和分治思想及其应用
- 3 递归和分治的思想
- 递归和分治思想1 – 数据结构和算法31
- 递归和分治思想2 – 数据结构和算法32
- 回归经典系列之递归和分治思想下
- 递归和分治思想的典型应用—汉诺塔问题
- 本文专注于<递归算法和分治思想>
- 本文专注于<递归算法和分治思想>
- 本文专注于<递归算法和分治思想>
- 分治策略结合递归思想求最大子序列和
- 递归和分治思想解全排列问题
- 递归和分治思想的典型应用—汉诺塔问题
- 分治法和递归
- 用SQL*PLUS创建网页
- 啊啊啊求c(n,k)
- 图之 邻接表 邻接矩阵 结构体定义
- redis学习教程
- centos php扩展开发流程
- 九、递归和分治思想
- DM9000网卡驱动
- Unity中利用A*算法实现简单寻路
- C++栈的地址变化
- ubuntu安装程序时遇到错误 you might want to run 'apt-get -f install' to correct these
- 文章标题
- python爬虫程序-登录
- windows API 实现精确的打点计时器
- Elevator