【推荐下载】()Hanoi塔问题的递归方法与非递归方法(java实现)
- 格式:docx
- 大小:20.38 KB
- 文档页数:6
java汉诺塔详解及实现代码java 汉诺塔详解及实现代码实现效果图打印的⽅法在 moveTheTopOne() ⽅法中被调⽤,调⽤该⽅法前打印出移动的⽅向--从X号塔往Y号塔汉诺塔要求:将第⼀座塔上的所有盘⼦,借助第⼆座塔,全部搬运到第三座塔上。
规则:⼀次只能搬运⼀个盘⼦,不准将⼤盘⼦落在⼩盘⼦上。
汉诺塔实现代码:public class NewHanoi {public static int tiers = 4; // tiers 层数private static List<String> pagoda1 = new ArrayList<String>(); // 静态指针private static List<String> pagoda2 = new ArrayList<String>();private static List<String> pagoda3 = new ArrayList<String>();// 映射,⽤来确定并打印塔的序号(使⽤⾓标),也可以使⽤ Mapprivate static List[] mapping = {pagoda1, pagoda2, pagoda3};public static void main(String[] args) {preparePagoda(pagoda1, tiers);System.out.println("初始状态:");printPagodas();hanoi(tiers, pagoda1, pagoda2, pagoda3);System.out.println("最后结果:");printPagodas();}// --准备盘⼦(添加-字符串) (源塔)上private static void preparePagoda(List<String> srcPagoda, int tiers) {// ⽤于拼装塔层的容器StringBuilder builder = new StringBuilder();// 源塔的每⼀层加盘⼦,从底层开始, i ‘代表'盘⼦的直径⼤⼩,等于组成盘⼦的"^"个数for(int i = tiers; i > 0; i--){// 每⼀层由 2*tiers-1 个格⼦组成,代表盘⼦⼤⼩的"^"格⼦由空格隔开for(int k = 0; k < tiers - i; k++) builder.append(" "); // 盘⼦左边的空格,数量为 [2*tiers-1-(2*i-1)]/2 = tiers-i, 右边相同 for(int j = 1; j <= 2*i-1; j++){ // 盘⼦所占格数if(j % 2 == 1) builder.append("^"); // 间隔摆放else builder.append(" ");}for(int k = 0; k < tiers - i; k++) builder.append(" "); // 盘⼦右边的空格srcPagoda.add(builder.toString()); // 添加到塔上builder.delete(0, builder.length()); // 下⼀循环前清空容器}}// --打印塔的现状private static void printPagodas(){// 打印层数为三座塔-现状的最⼤⾼度int len = Math.max(pagoda1.size(), Math.max(pagoda2.size(), pagoda3.size()));// ⽤于-塔的空层显⽰StringBuilder spaces = new StringBuilder();spaces.append("-"); // --添加塔的左外框for(int i = 0; i < 2*tiers-1; i++) spaces.append(" "); // 空层显⽰⽤空格spaces.append("-\t"); // --添加塔的右外框和塔间间隔for(int i = len - 1; i >= 0; i--){ // 从顶层开始// 三座塔同⼀⽔平⾯的塔层放在同⼀⾏显⽰// 当某个塔不存在此层时,List.get(index)会抛⾓标越界异常,使⽤try-catch处理:此层显⽰⼀层空格try { System.out.print("-" + pagoda1.get(i) + "-\t");} catch (Exception e1) { System.out.print(spaces);}try { System.out.print("-" + pagoda2.get(i) + "-\t");} catch (Exception e) { System.out.print(spaces);}try { System.out.print("-" + pagoda3.get(i) + "-\t");} catch (Exception e) { System.out.print(spaces);}System.out.print("\r\n");}}// 这个⽅法(递归的核⼼⽅法)从指定的源塔上移动-指定数量的盘⼦-到指定的⽬标塔上public static void hanoi(int moveNum, List<String> from, List<String> middle, List<String> to) {if(moveNum == 1){ // 递归到移动⼀个盘⼦时,使⽤ move ⽅法moveTheTopOne(from, to);return;}// 将实现分为三步,⼀,将源塔底盘上⽅的所有盘⼦移⾄中间塔(递归);⼆,将底盘移到⽬标塔;三,将中间塔上的所有盘⼦移到⽬标塔上(递归)。
Hanoi塔问题递归与非递归的...Hanoi塔问题的递归与非递归算法等价性证明[1]递归算法:Hanoi塔问题递归算法的简单描述如下:假设要解决的汉诺塔共有n个圆盘,对a塔上的全部n个圆盘从小到大顺序编号,最小的圆盘为1号,次之为2号,依次类推,则最下面的圆盘的编号为N。
第一步:若a塔上只有一个圆盘,即汉诺塔只有一层,则只需将这个盘从a塔上移到b塔上即可;第二步:对于一个有n(n>1)个圆盘的汉诺塔,将n个圆盘分成两部分:上面的n-1个圆盘和最下面的n号圆盘。
解决n个圆盘的汉诺塔,可以按下面的方式进行操作:1、将a塔上面的n-1个圆盘,借助b塔,移到c塔上;2、将a塔上剩余的n号盘子移到b塔上;3、将c塔上的n-1个盘子,借助a塔,移到b塔上。
void hannoi(int n,int a,int b,int c){if(n>0){hannoi(n-1,a,c,b);move(x,n,z) ;hannio(n-1,c,b,a);}}[2]非递归算法:名词解释第一类环:最小的那个圆环,就是在移动之前处在唯一有圆环的杆上最高位置的那个圆环。
第一类移动:第一类环的移动,就是第一类移动。
有用性结论1、在实现汉诺塔移动的过程中,第一类移动和非第一类移动交替出现。
2、第一类移动在一次移动中,要移动到的位置不会是上一次第一类移动移动之前圆环的位置。
换句话说,在只有三个杆的情况下,第一类移动是循环进行的。
算法思路1、n个圆盘的汉诺塔实现过程正好是2n步(用数学归纳法极易证明)。
2、由于第一步肯定是第一类移动,所以循环执行第奇数次时,都是第一类移动。
若将三个杆分别编为a、b、c,则第一类移动是从a杆移动到c杆,则当n为奇数时,第一类移动的次序为a到c到b 再回到a的循环。
当n为偶数时,第一类移动的次序为a到b到c再回到a的循环。
3、循环执行第偶数次时,都是非第一类移动。
比较三个杆的顶端的圆环,将两个顶端较大的圆环中较小的小圆环移动到顶端圆环最大的杆上即可。
hanoi塔递归算法Hanoi塔递归算法Hanoi塔是一个经典的数学问题,它的解法可以用递归算法来实现。
在这篇文章中,我们将介绍Hanoi塔问题的背景和递归算法的实现。
Hanoi塔问题的背景Hanoi塔问题是一个源于印度的传统数学问题,它的名字来源于印度的一个城市哈诺伊。
这个问题的描述如下:有三个柱子,分别为A、B、C,A柱子上有n个盘子,盘子大小不一,大的在下面,小的在上面。
现在要将A柱子上的所有盘子移动到C柱子上,移动过程中可以借助B柱子,但是要满足以下规则:1.每次只能移动一个盘子;2.大盘子不能放在小盘子上面。
这个问题看起来很简单,但是实际上它是一个非常复杂的问题。
当盘子数量较少时,我们可以手动模拟移动过程,但是当盘子数量增加时,手动模拟就变得非常困难。
因此,我们需要一种更加高效的算法来解决这个问题。
递归算法的实现递归算法是一种非常常见的算法,它的基本思想是将一个大问题分解成若干个小问题,然后逐个解决这些小问题,最终得到大问题的解。
在Hanoi塔问题中,我们可以使用递归算法来解决这个问题。
我们需要定义一个函数来实现移动盘子的操作。
这个函数需要接受三个参数:起始柱子、目标柱子和盘子数量。
函数的实现如下:```void move(int start, int end, int num){if (num == 1){cout << "Move disk " << num << " from " << start << " to " << end << endl;}else{int other = 6 - start - end;move(start, other, num - 1);cout << "Move disk " << num << " from " << start << " to " << end << endl;move(other, end, num - 1);}}```在这个函数中,我们首先判断盘子数量是否为1,如果是1,则直接将盘子从起始柱子移动到目标柱子。
Java 汉诺塔代码解析汉诺塔是一种经典的数学游戏,其目标是将一个叠放在柱子上的圆盘移动到另一个柱子上,且在移动过程中,圆盘始终要保持在上方的原则。
本文将介绍一个用 Java 语言实现的汉诺塔游戏的代码,并进行解析。
下面是本店铺为大家精心编写的4篇《Java 汉诺塔代码解析》,供大家借鉴与参考,希望对大家有所帮助。
《Java 汉诺塔代码解析》篇1汉诺塔游戏的基本规则是:有一个由三个柱子和若干个圆盘组成的游戏架,游戏目标是将所有圆盘从一个柱子移动到另一个柱子上,且在移动过程中,圆盘始终要保持在上方的原则。
下面是一个用 Java 语言实现的汉诺塔游戏的代码,并进行解析。
```javaimport java.util.Scanner;public class HanoiTower {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int[] hanoi = new int[n];for (int i = 0; i < n; i++) {hanoi[i] = scanner.nextInt();}scanner.close();// 计算最小步数int minSteps = 0;for (int i = 1; i < n; i++) {int temp = hanoi[i];for (int j = i - 1; j >= 0; j--) {if (temp < hanoi[j]) {minSteps++;temp = hanoi[j];}}}// 输出最小步数System.out.println("Minimum steps to move all disks from one rod to another: " + minSteps);}}```该代码实现了一个简单的汉诺塔游戏,用户可以通过输入圆盘的数量和每个圆盘的大小来开始游戏。
hanoi塔递归算法Hanoi塔问题是一道经典的递归问题,它源于印度传说中的一个古老故事。
这个故事讲述了一个寺庙里有三根柱子,其中一根柱子上有64个盘子,从小到大依次放置。
寺庙里的僧人们每天都要把这些盘子从一根柱子移动到另一根柱子上,并且规定在移动过程中不能把大盘子放在小盘子的上面。
这个问题的挑战在于如何用最少次数将所有盘子从起始柱移动到目标柱。
1. 问题描述假设有三根柱子,分别为A、B、C,其中A柱上有n个圆盘,大小依次递增。
现在需要将A柱上的所有圆盘移动到C柱上,可以借助B柱作为中转站,但是需要满足以下条件:1. 每次只能移动一个圆盘;2. 圆盘可以放置在空柱或者比它大的圆盘上;3. 需要保证始终满足第2条规则。
求解该问题所需最少步骤。
2. 递归算法实现Hanoi塔问题可以使用递归算法来进行求解。
递归算法的基本思路是将一个大问题分解成若干个小问题,通过不断递归调用函数来解决这些小问题。
对于Hanoi塔问题,我们可以将其分解成三个步骤:1. 将n-1个圆盘从A柱移动到B柱;2. 将第n个圆盘从A柱移动到C柱;3. 将n-1个圆盘从B柱移动到C柱。
这样一来,原问题就被分解成了三个规模更小的子问题。
对于每一个子问题,我们可以继续按照同样的方式进行分解,直到规模变得足够小,可以直接求解为止。
下面是Hanoi塔递归算法的实现代码:```void hanoi(int n, char A, char B, char C) {if (n == 1) {cout << "Move disk " << n << " from " << A << " to " << C << endl;} else {hanoi(n - 1, A, C, B);cout << "Move disk " << n << " from " << A << " to " << C << endl;hanoi(n - 1, B, A, C);}}```其中,参数n表示当前需要移动的圆盘数量;参数A、B、C表示三根柱子的名称。
C|用递归和非递归方法求解汉诺塔问题汉诺塔(Tower of Hanoi,又称河内塔)问题是源于印度一个古老传说的益智玩具。
大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。
大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。
并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
当盘子的个数为n时,移动的次数应等于2^n – 1。
后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了。
首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:若n为偶数,按顺时针方向依次摆放 A、B、C;若n为奇数,按顺时针方向依次摆放 A、C、B。
① 按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A。
② 接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。
即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘。
这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的。
③ 反复进行①②操作,最后就能按规定完成汉诺塔的移动。
所以结果非常简单,就是按照移动规则向一个方向移动金片:如3阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C// 用递归求解汉诺塔问题int step=1; // 整型全局变量,预置1,步数void move(int, char, char, char);// 声明要用到的被调用函数void main(){int n;// 整型变量,n为盘数,printf("请输入盘数 n=");// 提示信息scanf("%d",&n);// 输入正整数nprintf("在3根柱子上移%d只盘的步骤为: ",n);move(n,'a','b','c');// 调用函数move(n,'a','b','c')system("pause");}void move(int m, char p, char q, char r){// 自定义函数体开始if (m==1)// 如果m为1,则为直接可解结点,{// 直接可解结点,输出移盘信息printf("[%d] move 1# from %c to %c ",step,p,r);step++;// 步数加1}else// 如果不为1,则要调用move(m-1){move(m-1,p,r,q);// 递归调用move(m-1)//直接可解结点,输出移盘信息printf("[%d] move %d# from %c to %c ", step, m, p, r);step++;// 步数加1move(m-1,q,p,r);// 递归调用move(m-1)}}//自定义函数体结束运行结果:请输入盘数 n=4在3根柱子上移4只盘的步骤为:[1] move 1# from a to b[2] move 2# from a to c[3] move 1# from b to c[4] move 3# from a to b[5] move 1# from c to a[6] move 2# from c to b[7] move 1# from a to b[8] move 4# from a to c[9] move 1# from b to c[10] move 2# from b to a[11] move 1# from c to a[12] move 3# from b to c[13] move 1# from a to b[14] move 2# from a to c[15] move 1# from b to c非递归方法:#include <iostream>using namespace std;//圆盘的个数最多为64const int MAX = 64;//用来表示每根柱子的信息struct st{int s[MAX]; //柱子上的圆盘存储情况int top; //栈顶,用来最上面的圆盘char name; //柱子的名字,可以是A,B,C中的一个int Top()//取栈顶元素{return s[top];}int Pop()//出栈{return s[top--];}void Push(int x)//入栈{s[++top] = x;}} ;long Pow(int x, int y); //计算x^yvoid Creat(st ta[], int n); //给结构数组设置初值void Hannuota(st ta[], long max); //移动汉诺塔的主要函数int main(void){int n;cout << "输入圆盘的个数:" << endl;cin >> n; //输入圆盘的个数st ta[3]; //三根柱子的信息用结构数组存储Creat(ta, n); //给结构数组设置初值long max = Pow(2, n) - 1;//动的次数应等于2^n - 1Hannuota(ta, max);//移动汉诺塔的主要函数system("pause");return 0;}void Creat(st ta[], int n){ta[0].name = 'A';ta[0].top = n-1;//把所有的圆盘按从大到小的顺序放在柱子A上for (int i=0; i<n; i++)ta[0].s[i] = n - i;//柱子B,C上开始没有没有圆盘ta[1].top = ta[2].top = 0;for (i=0; i<n; i++)ta[1].s[i] = ta[2].s[i] = 0;//若n为偶数,按顺时针方向依次摆放 AB Cif (n%2 == 0){ta[1].name = 'B';ta[2].name = 'C';}else //若n为奇数,按顺时针方向依次摆放 A C B{ta[1].name = 'C';ta[2].name = 'B';}}long Pow(int x, int y){long sum = 1;for (int i=0; i<y; i++)sum *= x;return sum;}void Hannuota(st ta[], long max){int k = 0; //累计移动的次数int i = 0;int ch;while (k < max){//按顺时针方向把圆盘1从现在的柱子移动到下一根柱子ch = ta[i%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " <<"Move disk " << ch << " from " << ta[i%3].name <<" to " << ta[(i+1)%3].name << endl;i++;//把另外两根柱子上可以移动的圆盘移动到新的柱子上if (k < max){ //把非空柱子上的圆盘移动到空柱子上,当两根柱子都为空时,移动较小的圆盘if (ta[(i+1)%3].T op() == 0 ||ta[(i-1)%3].Top() > 0 &&ta[(i+1)%3].T op() > ta[(i-1)%3].Top()){ch = ta[(i-1)%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " << "Move disk "<< ch << " from " << ta[(i-1)%3].name<< " to " << ta[(i+1)%3].name << endl;}else{ch = ta[(i+1)%3].Pop();ta[(i-1)%3].Push(ch);cout << ++k << ": " << "Move disk "<< ch << " from " << ta[(i+1)%3].name<< " to " << ta[(i-1)%3].name << endl;}}}}运行结果:输入圆盘的个数:5步骤:1: Move disk 1 from A to C 2: Move disk 2 from A to B 3: Move disk 1 from C to B 4: Move disk 3 from A to C 5: Move disk 1 from B to A 6: Move disk 2 from B to C 7: Move disk 1 from A to C 8: Move disk 4 from A to B 9: Move disk 1 from C to B 10: Move disk 2 from C to A 11: Move disk 1 from B to A 12: Move disk 3 from C to B 13: Move disk 1 from A to C 14: Move disk 2 from A to B 15: Move disk 1 from C to B 16: Move disk 5 from A to C 17: Move disk 1 from B to A 18: Move disk 2 from B to C 19: Move disk 1 from A to C 20: Move disk 3 from B to A 21: Move disk 1 from C to B 22: Move disk 2 from C to A23: Move disk 1 from B to A24: Move disk 4 from B to C25: Move disk 1 from A to C26: Move disk 2 from A to B27: Move disk 1 from C to B28: Move disk 3 from A to C29: Move disk 1 from B to A30: Move disk 2 from B to C31: Move disk 1 from A to C -End-。
汉诺塔问题的非递归非堆栈算法汉诺塔问题的非递归非堆栈算法(一)#i nclude <iostream.h>#i nclude <math.h>#define maxno 10000int step_d,step_s,no;//定义将要行进的步数void main(){cout<<"请输入数字(1-64):";cin>>no;//获取实际的塔片数//初始化int **p=new int*[3];p[0]=new int[no+1];p[1]=new int[no+1];p[2]=new int[no+1];p[0][0]=maxno;p[1][0]=maxno;p[2][0]=maxno;for(int count=1;count<=no;count++){p[0][count]=no-count+1;p[1][count]=0;p[2][count]=0;}//初始化完毕if(fmod(no,2)){step_s=2;step_d=1;}else {step_s=1;step_d=2;}//判断奇数盘的步数和偶数盘的步数int from,to;from=0;to=step_s+from;p[0]=&p[0][no];while(*(p[0]) != *(p[1])){cout<<"从柱:"<<from+1<<" 到柱: "<<to+1<<endl;*(++p[to])=*(p[from]);*(p[from]--)=0;//以下求得下一步将要From移动的柱子switch(to){case 2:if(*(p[0]) < *(p[1]))from=0;else from=1;break;case 1:if(*(p[0]) < *(p[2]))from=0;else from=2;break;case 0:if(*(p[2]) < *(p[1]))from=2;else from=1;break;}//以下一行求得下一步将要移动到的柱子if(fmod(*(p[from]),2))to=fmod(from+step_s,3);else to=fmod(from+step_d,3); }char c;cin>>c;}汉诺塔问题的非递归非堆栈算法(二)前一种方法的/*原理:如果把三个柱子围成一个环,盘子总数为N,其移动的规律是:如果N为偶数:奇数号盘每次2步;偶数号盘每次1步;如果N为奇数:奇数号盘每次1步;偶数号盘每次2步;至于下一步该移动哪个柱子上的盘子,通过大小和顺序即可判断。
简述java递归与非递归算法,0-100求和,斐波那契数列,八皇后,汉诺塔问题一:什么是递归算法?递归算法就是直接或者间接的调用自己的方法,在达到一个条件的时候停止调用(递归出口),所以一定要找准好条件,让递归停止,否则就会是无限进行下去二:递归程序设计的关键1:找出调用中所需要的参数2:返回的结果3:递归调用结束的条件三:递归程序注意1:要有方法中自己调用自己2:要有分支结构3:要有结束的条件四:简单叙述递归函数的优缺点优点:1:简洁清晰,实现容易,可读性好2:在遍历的算法中,递归比循环更为简单缺点:1:效率低,使用递归函数是有空间和时间的消耗的。
并且很多计算都是重复的,对性能有较大的影响2:可能导致调用栈的溢出,每一次函数调用,在内存栈中分配空间,而每一个栈的容量是有限的,当递归的层级太多的时候,超出栈的容量,就会导致栈溢出。
3:递归函数需要系统的堆栈,空间消耗比非递归的要消耗很多,并且深度太大的话,系统可能会支撑不住五:注意a.简单的用循环,复杂的用递归(可以实现大部分相关问题)b.有规律的问题,循环不方便时,使用递归是不错的建议。
c.循环方法比递归方法快,避免了一系列函数的调用,返回中涉及参数传递,返回值的额外开销,每递归一次,栈内存就多占用一截d.能用循环,就尽量不要用递归.......e.当递归中出现分支结构的时候(可以出现多个分支),注意每一个分支结构都要有结束条件。
f.只要函数调用了自己,不论间接或者直接,都算递归。
g.非递归函数效率高,但是较难编程,可读性较差六:相关递归问题1:斐波那契数列for循环:1 import java.util.Scanner;2 public class Day1{3 public static void main(String[] args){4 System.out.println("请输入位数所显示的数字:");5 Scanner sc = new Scanner(System.in);6 int x = sc.nextInt();7 int x1 = 1;8 int x2 = 1;9 int x3 = 0;10 int add = 2;11 System.out.printf("数列分别为:\n1\t1\t");12 for(int i = 1;i<=x-2;i )13 {14 //因为前两项是一样的,从第三项开始出现不同的数字,所以进行减二15 //所定义了三个变量,x1代表第一个数字,x2代表第二个数字,x3代表第一个数字与第二个数字的和,所赋予他们的意义不要改变16 x3 = x1 x2;17 add = add x3;19 x2 = x3;20 System.out.printf("%d\t",x3);21 }22 System.out.println("\n第" x "项数字为:" x3);23 System.out.println("前" x "项和为:" add);24 }25 }递归算法:1 public class Day1{2 public static int f(int n){3 if(n==1||n==2){4 return 1;5 }else{6 return f(n-1) f(n-2);7 }8 }9 public static void main(String[] args){10 System.out.println(f(5));11 }12 }想法:递归算法对于一些问题来说是真的简单,斐波那契数列的公式:fn = f(n-1) f(n - 2) (n >= 2),考虑前两个数字的话,就是1,由于从0开始,可以理解为F0 = 0; F1 = 1; F1 = 1;正好是与计算机相对应2: 0-100数字进行相加for循环:1 public class Day1{2 public static void main(String[] args){4 for(int i = 0;i <= 100;i ){5 add = add i;6 }7 System.out.println("0-100的和为:" add);8 }9 }递归算法:1 public class Day1{2 public static int f(int n){3 if(n>0)4 return n f(n-1);5 return 0;6 }//尽量有一个临界的点,if(n == 1)return 1;else return n f(n-1);7 public static void main(String[] args){8 System.out.println("0-100的和为:" f(100));9 }10 }3:八皇后摘自百度百科,注释比较明细:1 public class Day1 {2 private int[] column; //同栏是否有皇后,1表示有3 private int[] rup; //右上至左下是否有皇后4 private int[] lup; //左上至右下是否有皇后5 private int[] queen; //解答6 private int num; //解答编号78 public Day1() {9 column = new int[8 1];10 rup = new int[(2*8) 1];11 lup = new int[(2*8) 1];12 for (int i = 1; i <= 8; i )13 column[i] = 0;14 for (int i = 1; i <= (2*8); i )15 rup[i] = lup[i] = 0; //初始定义全部无皇后16 queen = new int[8 1];17 }1819 public void backtrack(int i) {20 if (i > 8) {21 showAnswer();22 } else {23 for (int j = 1; j <= 8; j ) {24 if ((column[j] == 0) && (rup[i j] == 0) && (lup[i-j 8] == 0)) {25 //若无皇后26 queen[i] = j; //设定为占用27 column[j] = rup[i j] = lup[i-j 8] = 1;28 backtrack(i 1); //循环调用29 column[j] = rup[i j] = lup[i-j 8] = 0;30 }31 }32 }33 }3435 protected void showAnswer() {36 num ;37 System.out.println("\n解答" num);38 for (int y = 1; y <= 8; y ) {39 for (int x = 1; x <= 8; x ) {40 if(queen[y]==x) {41 System.out.print("Q");42 } else {43 System.out.print(".");44 }45 }46 System.out.println();47 }48 }4950 public static void main(String[] args) {51 Day1 queen = new Day1();52 queen.backtrack(1);53 }54 }汉诺塔问题:稍后继续编辑,由于零散时间写的博客,过两三天就会补齐七:总结贵在坚持吧,最近被些事情忙怀了,毫不夸张的说,感觉生活下去的勇气都是断断续续的,有朋友不断的鼓励我,天将降大任于斯人也,必须苦其心志,劳其筋骨。
(原创)Hanoi 塔问题的递归方法与非递归方法(java 实现) 2015/11/18 135950 本文讨论了Hanoi 塔问题的递归方法与非递归方法,给出
了java 实现的代码,并比较了它们的效率。
法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯
(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。
印度教的主神梵天在创
造世界的时候,在其中一根针上从下到上地穿好了由大到小的64 片金片,这就是所
谓的汉诺塔。
不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次
只移动一片,不管在哪根针上,小片必须在大片上面。
僧侣们预言,当所有的金片
都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵
塔、庙宇和众生也都将同归于尽。
文章中我们假设汉诺塔个数为正整数n,三个盘子为A,B,C,其中C 是中介盘,我
们要遵守移动规则将A 上的盘子要全部通过C 移动到B。
1.递归方法如果汉诺塔上盘子个数n=1 时显然直接将A 上的盘子移动到B 即可,当n=2 时,方法也很简单,只要将第一块盘子先从A 移动到C,再将第二块盘子
从A 移动到B,再将第一块盘子从C 移动到A。
实际上,表达的时候不必要强调第几
块盘子,而只需要像从A 移动到B 这样描述,也能清楚的知道意思(因为总是只能移
动每个汉诺塔最顶上的盘子)。
那么n=2 时解决办法的表示就是:A- C,A- B,C- B。
下
面我们都采用这种简洁明了的表示。
要知道如何将n 块盘子从A 通过C 移动到
B,我们可以先将上面的n-1 块盘子从A 通过B 移动到C,再将最大的盘子从A 移
动到B,这时再将上面的n-1 块盘子从C 通过A 移动到B。
这就是递归算法解决
Hanoi 塔问题的思路。
代码如下:
/** * 将A 汉诺塔上的n 个盘子通过C 移动到B 的递归方法* @param n //汉诺
塔上盘子的个数* @param A //开始时有盘子的汉诺塔* @param B //要将盘子移动
到上面的目标汉诺塔* @param C //中介汉诺塔* @throws IllegalArgumentException when n =0 */ public static void HanoiTowers1(int n,char A,char B,char C){ if(n =0){ throw new IllegalArgumentException(“n must be =1”);} if(n==1){。