热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

非递归的汉诺塔程序

这是我写的非递归的汉诺塔程序,有兴趣的可以看看。还可以帮我优化优化,我的水平很差,写得也就很烂了。如果有兴趣,可以继续优化一下。我用的是最简单的方法,什么都没用到,就用到了一个数组,本来想用链
这是我写的非递归的汉诺塔程序,有兴趣的可以看看。还可以帮我优化优化,我的水平很差,写得也就很烂了。如果有兴趣,可以继续优化一下。

我用的是最简单的方法,什么都没用到,就用到了一个数组,本来想用链表的,后来想想算了。

这个程序的数学原理是这样的:

首先必须确定一个移动的方向,比如A->B->C,或者A->C->B,但这个顺序一旦却确定后就不可以再改变了的,否则永远都不会成功。
然后一直按下面两个步骤循环,直到全部完成。

1、把第一片移到下一个位置,比如原来在A,顺序是A->B->C,哪就是移到B,原来在B的就是到C,在C的      就是到A
2、把除第一片以外,可以移动的另外一片移动到可以移动的为止,这个看似模糊,但其实关系是确定的,这个时候只有一片可以移动,而且位置也只有一个可以让它移动。

就是这么两个步骤,用来完成汉诺塔

下面是我的程序

(注:我在程序中作了个弊,如果是奇数片,那顺序一定是A->C->B,(其中A是原柱,B是辅柱,C是目的柱;如果是偶数片,那顺序一定是A->B->C)

#include 
//#include 
//#include 
#include 

void henit(int n, char fromreg, char auxreg, char toreg)
{
 char heni[255] = {0}, tmptoreg;
 int i;

 tmptoreg = toreg;

 if(n%2)
 {
int tmp = auxreg;
auxreg = toreg;
toreg = tmp;
 }

 for (i=1; i<=n; i++)
 {
 heni[i] = fromreg;
 }

 while (1)
 {
   if (heni[1] == fromreg)
   {
   heni[1] = auxreg;
   printf("\t1: %c-->%c\n", fromreg, auxreg);
   }
   else
   if (heni[1] == auxreg)
   {
   heni[1] = toreg;
   printf("\t1: %c-->%c\n", auxreg, toreg);
   }
   else
   if (heni[1] == toreg)
   {
   heni[1] = fromreg;
   printf("\t1: %c-->%c\n", toreg, fromreg);
   }

   for (i = 1; heni[i] == tmptoreg && i<=n; i++)
   ;
   if(i>n)
   break;

for(i=1;i<=n;i++)
if(heni[i] == fromreg) break;
if(i>n)
{
heni[n+1]=fromreg;
goto Next;
}
for(i=1; i<=n; i++)
if(heni[i] == auxreg) break;
if(i>n)
{
heni[n+1]=auxreg;
goto Next;
}
for(i=1; i<=n; i++)
if(heni[i] == toreg) break;
if(i>n)
{
heni[n+1]=toreg;
goto Next;
}

Next:
   for(i=2; heni[i] == heni[1] && i<=n ; i++)
;
   for(int j=i+1; j<=n+1; j++)
   {
   if ((heni[j] != heni[1]) && (heni[j] != heni[i]) && (i<=n))
   {
printf("\t%d: %c-->%c\n", i, heni[i], heni[j]);
heni[i] = heni[j];
break;
   }
   }
 }
}

int main(void)
{
int n = 0;
//time_t start_t, end_t;
struct time start_t, end_t;

//clrscr();
printf("Input your number:");
scanf("%d", &n);
//start_t = time(NULL);
gettime(&start_t);
henit(n, 'A', 'B', 'C');
//end_t = time(NULL);
gettime(&end_t);
//printf("Ok,it is down now! use %d seconds", int(end_t - start_t));
    printf("Ok,it is down now! use %2d:%02d:%02d.%02d", \
            (end_t.ti_hour-start_t.ti_hour), (end_t.ti_min-start_t.ti_min), \
            (end_t.ti_sec-start_t.ti_sec), (end_t.ti_hund-start_t.ti_hund));
getchar();
getchar();
return 0;
}

经过我的不正规的测试,要比递归的快很多。哪位懂测试的,可以告诉我怎样测试会比较准确,谢谢!

7 个解决方案

#1


太长了!
帮你顶~~~~`

#2


递归法肯定慢。
调用函数需要额外的时间,入栈、保护现场、出栈等等。

#3



不错

#4


我也觉得程序有点陇长了,哪位高手可以优化优化?

#5


搜到一个,
贴出来看看。


汉诺塔的递归和非递归算法,写着玩玩。
http://blog.blogchina.com/refer.243908.html

#include 

#define MAXSTACK 10   /* 栈的最大深度 */

int c = 1; /* 一个全局变量,表示目前移动的步数 */

struct hanoi { /* 存储汉诺塔的结构,包括盘的数目和三个盘的名称 */
 int n;
 char x, y, z;
};

void move(char x, int n, char y) /* 移动函数,表示把某个盘从某根针移动到另一根针 */
{
 printf("%d. Move disk %d from %c to %cn", c++, n, x, y);
}

void hanoi(int n, char x, char y, char z) /* 汉诺塔的递归算法 */
{
 if (1 == n)
  move(x, 1, z);
 else {
  hanoi(n - 1, x, z, y);
  move(x, n, z);
  hanoi(n - 1, y, x, z);
 }
}

void push(struct hanoi *p, int top, char x, char y, char z,int n)
{
 p[top+1].n = n - 1;  
 p[top+1].x = x;  
 p[top+1].y = y;  
 p[top+1].z = z; 
}

void unreverse_hanoi(struct hanoi *p) /* 汉诺塔的非递归算法 */
{
 int top = 0;

 while (top >= 0) {
  while (p[top].n > 1) { /* 向左走到尽头 */
   push(p, top, p[top].x, p[top].z, p[top].y, p[top].n);
   top++;
  }
  if (p[top].n == 1) { /* 叶子结点 */
   move(p[top].x, 1, p[top].z);
   top--;
  }
  if (top >= 0) { /* 向右走一步 */
   move(p[top].x, p[top].n, p[top].z);
   top--;
   push(p, top, p[top+1].y, p[top+1].x, p[top+1].z, p[top+1].n);
   top++;
  }
 }
}

int main(void)
{
 int i;
 printf("reverse program:n");
 hanoi(3, 'x', 'y', 'z');
 printf("unreverse program:n");
 struct hanoi p[MAXSTACK];
 c = 1;
 p[0].n = 3;
 p[0].x = 'x', p[0].y = 'y', p[0].z = 'z';
 unreverse_hanoi(p);

 return 0;
}

 

 



#6


这个是分别用两种算法求的

#7


最后这个帖子不错,我想给分,怎么给的呀?我刚注册的,不好意思,哪位教教我呀

推荐阅读
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
author-avatar
chen
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有