`
hy2012_campus
  • 浏览: 30636 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类
最新评论

hanoi算法递归非递归以及扩展

 
阅读更多

这是个汉诺塔程序,在调试的时候,输入的数字最好不要大于15,因为每大一个数所得的结果的步骤都会多一倍。如果你有耐心等待结果的话除外。汉诺塔是在欧洲流行的一种游戏,有a,b,c三个竿。a竿上有若干个由大到小的圆盘,大的在下面,小的在上面,b,c都是空杆,请你把a杆上的圆盘都倒到别的杆上,或b或c,在倒盘的过程中不可以大的压小的,实例程序如下:

#include <stdio.h>
#include <stdlib.h>
void move(char x,char y) {
	printf("%c-->%c\n",x,y);
} 
void hanoi (int n,char one ,char two,char three) {
	if(n==1) 
		move (one ,three); 
	else {
		hanoi (n-1,one,three,two); 
		move(one,three); 
		hanoi(n-1,two,one,three); 
	} 
} 
int main() 
{
	int m; 
	printf("input the number of diskes:"); 
	scanf("%d",&m); 
	printf("the step to moving %3d diskes:\n",m); 
	hanoi(m,'A','B','C'); 
	system("pause");
} 

 

#include <stdio.h>
#include <conio.h>
int i=0;
void movedisc(unsigned n,char fromneedle,char toneedle,char usingneedle){
	if(n>0){
		movedisc(n-1,fromneedle,usingneedle,toneedle);
		i++;
		switch(fromneedle){
            case 'a':
                switch(toneedle){
		            case 'b':printf("\t[%d]:\t%2d------>%2d\n",i,n,n);
						break;
					case 'c':printf("\t[%d]:\t%2d------------->%2d\n",i,n,n);
						break;
                }
			    break;
            case 'b':
                switch(toneedle){
		            case 'a':printf("\t[%d]:\t%2d<----------%2d\n",i,n,n);
						break;
					case 'c':printf("\t[%d]:\t\t%2d------>%2d\n",i,n,n);
						break;
				 }
			     break;
            case 'c':
                switch(toneedle){
		            case 'a':printf("\t[%d]:\t%2d<--------------%2d\n",i,n,n);
						break;
					case 'b':printf("\t[%d]:\t\t%2d<--------%2d\n",i,n,n);
						break;
                }
			    break;
		}
        movedisc(n-1,usingneedle,toneedle,fromneedle);
	}
}
int main(){
	unsigned n;
	printf("Please enter the number of discs: ");
	scanf("%d",&n);
	printf("\tneedle:\ta\t b\t c\n");
	movedisc(n,'a','c','b');
	printf("\t Total: %d\n",i);
	getch();
}

 

#include <stdio.h>
#define width (rings+1)

int main(){
	int rings, last, next, x, z[500], s[3];

	printf("how many rings?  "); scanf("%d",&rings);

	for(x=1; x<=rings; x++)  /* put rings on first peg */
		z[x]=width-x;
	for(x=0; x<=2*width; x+=width)  /* set base for each peg  */
		z[x]=1000;

	/* if even number of rings, put first ring on second peg; if odd, on third */

	if(rings%2==0){
		last=1; s[2]=0; s[1]=1;
	    z[width+1]=z[rings];
  	}else{
		last=2; s[1]=0; s[2]=1;
		z[2*width+1]=z[rings];
  	}

	printf("from 1 to %d\n",last+1); 
	s[0]=rings-1;

	while(s[0]+s[1]){ 		/* while first and second pegs aren't empty */
      
		/* next ring to move is smaller of rings on the two pegs not moved onto last */

		if(last==0)  
			next=z[width+s[1]]<z[2*width+s[2]]?1:2;
		if(last==1)  
			next=z[s[0]]<z[2*width+s[2]]?0:2;
		if(last==2)  
			next=z[s[0]]<z[width+s[1]]?0:1;

		/* top ring of 'to' peg must be larger and an even 'distance' away */

		if((z[next*width+s[next]])>(z[last*width+s[last]])||((z[last*width+s[last]]-z[next*width+s[next]])%2==0))
			last=3-next-last;

		printf("from %d to %d\n",next+1,last+1);

		s[next]=s[next]-1; s[last]=s[last]+1; /* move from 'next' to 'last' peg */
		z[last*width+s[last]]=z[next*width+s[next]+1];
    }
}

 

#include <stdio.h>

//--------------------------------------------------------
// 打印搬运动作
//--------------------------------------------------------
int MoveIt(int x,int Source,int Target)
{
    printf("Move %d From %d to %d\n",x,Source,Target);
    return 0;
}

//--------------------------------------------------------
// 用 4 根柱子移动盘子
// n 是盘子个数,编号从1 到 n
// First 是源柱子号
// Second Third 是两根过渡柱
// Fourth 是目标柱
//--------------------------------------------------------
int MoveHanoi(int n,int First,int Second,int Third,int Fourth)
{
    if (n<1) return 0;                   // 如果没有盘子就返回
    if (n==1)                            // 如果只有一个盘子
    {
        MoveIt(n,First,Fourth);          // 就直接从源柱子移到目标柱子上
        return 0;
    }
    if (n==2)                            // 如果有两个盘子
    {
        MoveIt(n-1,First,Second);        // 把上面的那片移到一个过渡柱上
        MoveIt(n,First,Fourth);          // 把下面的那片移到目标柱上
        MoveIt(n-1,Second,Fourth);      // 再把第 1 片从过渡柱移到目标柱上
		return 0;
    }
    if (n==3)                            // 如果有 3 片盘子
    {
        MoveIt(n-2,First,Second);        // 把最小的盘子移到一个过渡柱上
        MoveIt(n-1,First,Third);        // 把中间盘子移到另一过渡柱上
        MoveIt(n,First,Fourth);          // 把最大的盘子移到目标柱上
        MoveIt(n-1,Third,Fourth);        // 把中间盘子移到目标柱上
        MoveIt(n-2,Second,Fourth);      // 把最小的盘子移到目标柱上
        return 0;
    }
                                        // 递归地把上面 n-2 盘子移到一个过渡柱上
                                        // 留下最大的两个盘子
    MoveHanoi(n-2,First,Third,Fourth,Second);
    MoveIt(n-1,First,Third);            // 把倒数第 2 个盘子移到另一个过渡柱上
    MoveIt(n,First,Fourth);              // 把最底下的盘子移到目标柱上
    MoveIt(n-1,Third,Fourth);            // 把倒数第 2 个盘子移到目标柱上
                                        // 递归地把 n-2 个盘子从过渡柱上移到目标柱上
    MoveHanoi(n-2,Second,First,Third,Fourth);
    return 0;
}

int main()
{
	int num;
	scanf("%d",&num);
    MoveHanoi(num,1,2,3,4);
    return 0;
}

 

#include <stdio.h>
#include <math.h>
#define MAX_N 1000

int main(){
	double f[MAX_N];
	int n,i,j;
	double maxvalue,curvalue;
	printf("Please input count:");
	scanf("%d",&n);
	if(n>=MAX_N){
		printf("Out of range\n");
		return -1;
	}
	f[1]=1.0,f[2]=3.0;
	for(j=3;j<=n;j++){
		maxvalue=pow(2,j);
		for(i=1;i<j;i++){
			curvalue=2*f[i]+pow(2,j-i)-1;
			if(curvalue<maxvalue)
			maxvalue=curvalue;
			else
			break;
		}
		f[j]=maxvalue;
	}
	for(i=1;i<=n;i++)
		printf("m[%d]=%f\n",i,f[i]);
	return 0;
} 

 不得不佩服递归魅力,非递归实现方式实现起来让人有点费解。

分享到:
评论

相关推荐

    hanoi(汉诺塔)问题的非递归实现

    ### hanoi(汉诺塔)问题的非递归实现 #### 概述 汉诺塔问题是一种经典的递归算法示例,在计算机科学领域被广泛应用于教授递归思想和技术。传统解决汉诺塔问题的方法通常采用递归算法,尽管这种方法结构清晰易懂,...

    hanoi塔改进.rar

    汉诺塔(Hanoi Tower)是一个经典的递归问题,源于19世纪法国数学家爱德华·卢卡斯提出的思考实验。在这个问题中,我们有三根柱子和一堆大小不一的圆盘,所有圆盘起始都放在第一根柱子上,按照从大到小的顺序...

    经典算法(C语言)包含51个经典算法的C语言实现

    1. **汉诺塔(Hanoi Tower)**:这是一个递归算法问题,目标是将一个柱子上的所有圆盘移动到另一个柱子上,遵循每次只能移动一个圆盘且大盘子不能在小盘子之上的规则。 2. **斐波那契数列(Fibonacci Sequence)**:...

    数据结构读书精彩笔记.pdf

    同时,还介绍了栈与递归的关系,以及借助栈将递归转向于非递归的经典算法,包括n!阶乘问题、Fib数列问题、Hanoi问题、背包问题等。 第四章 串 本章主要介绍了串的基本概念,包括串与线性表的关系、空串与空格串的...

    汉诺塔问题 仅限11个盘子 效率较高

    根据给定的信息,本文将对汉诺塔问题的非递归解决方案进行详细的解析与说明。 ### 汉诺塔问题概述 汉诺塔问题(Hanoi Tower)是一种经典...对于理解和掌握非递归算法解决问题的方法,这种方法提供了一个很好的实例。

    汉诺塔c程序

    ### 汉诺塔C程序知识点详解 #### 一、汉诺塔问题介绍 汉诺塔(Hanoi Tower)...3. **非递归实现**: 如何不使用递归实现汉诺塔问题? 以上是对“汉诺塔C程序”的详细介绍,希望对读者理解汉诺塔问题及其实现有所帮助。

    汉诺塔游戏的设计

    因此,实际应用中可能需要考虑优化,如使用迭代而非递归,或者结合用户交互以分步骤进行。 此外,除了基本的命令行界面,还可以扩展此程序,例如添加图形用户界面(GUI),使得用户能够通过点击和拖拽盘子进行操作...

    Java实验汉罗塔共54页.pdf.zip

    6. **优化与扩展**:可能包括非递归解法、优化技巧,或者扩展问题,如多个起点或终点的汉罗塔问题。 7. **实践环节**:提供练习题目,让学生自己动手编写代码并进行测试。 8. **错误处理和调试技巧**:讲解如何处理...

    C++课程设计(汉诺塔)代码及报告

    例如,可以分析不同圆盘数量下的移动步数,讨论递归深度与时间复杂度的关系,或者探讨如何改进代码以提高效率,比如使用迭代而非递归。 在课程设计过程中,除了编写代码外,还要注意代码风格、注释清晰、文档完整。...

    GP2Hanoi-开源

    通过研究其源代码,可以了解如何使用SDL库进行游戏编程,以及如何解决复杂问题如汉诺塔的递归算法。 总的来说,GP2Hanoi是一个结合了经典游戏与现代技术的开源项目,不仅为玩家提供了娱乐,也为开发者提供了学习和...

    c++汉诺塔问题.md

    - **优化思路**:虽然递归是解决汉诺塔问题的一种直观方法,但对于大量圆盘的情况,可以考虑非递归算法或其他优化方案以提高效率。 通过以上分析,我们不仅了解了汉诺塔问题的基本概念和解决策略,还深入学习了如何...

    标准二维表

    本压缩包提供了解决此类问题的三种高效算法,可以应对超过1000个数据规模的挑战,甚至扩展到10000以上的情况。这种能力对于处理复杂计算和大数据量的场景至关重要。 首先,我们要理解“二维表”在计算机科学中的...

    SGU题库整合 Volume (200 - 299) pdf版

    **递归算法**: 利用递归的思想解决问题。 2. **优化策略**: 针对不同的变种提出相应的优化方案。 - **实际意义**: 不仅有助于提高递归思维能力,还能应用于多领域问题解决。 #### 203. Hyperhuffman - **背景**: ...

    109、第2课 移梵塔--2020.03.26a.pdf

    - **汉诺塔问题**(Hanoi Tower Problem)是一个经典的数学谜题,同时也常用于教授递归的概念。 - 该问题描述如下:有三个柱子(通常标记为A、B、C),以及若干个不同大小的圆盘。初始状态下,所有圆盘按照从小到大...

Global site tag (gtag.js) - Google Analytics