C语言汉诺塔实验非递归方法,用非递归的方法实现汉诺塔问题

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

26                }

27

28                if (last != britop && ((britop%2 && britop>srctop) || ((britop%2==0) && britop>dsttop)))

29                {

30                       sbri.pop();

31                       last = britop;

32                       britop % 2 ? ssrc.push(britop) : sdst.push(britop);

33

34                       if (britop % 2)

35                              cout<

36                       else

37                              cout<

38                }

39

40                if (last != dsttop && ((dsttop%2 && dsttop>britop) || ((dsttop%2==0) && dsttop>srctop)))

41                {

42                       sdst.pop();

43                       last = dsttop;

44                       dsttop % 2 ? sbri.push(dsttop) : ssrc.push(dsttop);

45                       if (dsttop % 2)

46                              cout<

47                       else

48                             cout<

49                }

50         }

51 }

看上面的代码好象复杂了点,不过主要还是因为判别的条件太复杂了,才会导致这段代码这么难懂。在这个while循环里面有3个if语句都在判定当前的盘子是否可以被移动,如果可以移动就移动它并且打印出来。

对于一个盘子要可以移动要满足以下2个条件

1.  前一次没有被移动过也就是不能够等于last

2.  盘子的编号必须要大于目标盘最上面的盘子的编号

这两个条件都要满足才能移动,可以证明在任何时候可以移动的盘子都是唯一的。

为了便于和开始的方法比较,在输出的时候对盘子的编号做了个转换,还是把它还原成原来的编号的方法。也就是编号小的在上,编号大的在下。上面我这个写法实在是太不简洁了,希望有写得更好的替换它。

3.递归的方法

尽管书上已经有递归的方法,不过我还是要给出我的递归的方法,作为参考。然后用于性能的比较。

3 #define move(disk,src,dst) cout<

4 void hanoi_r(int size,char src,char dst,char bri)

5 {

6         if (size == 1)

7                move(size,src,dst);

8         else

9         {

10                hanoi_r(size-1,src,bri,dst);

11                move(size,src,dst);

12                hanoi_r(size-1,bri,dst,src);

13         }

14 }

4.各种方法的比较

有不同的实现方法,当然就有对比,我一直以为非递归的方法要比递归的方法要快一些,不过结果好象并不是这样。

由于打印输出需要消耗部少的时间,所以我就把它去掉了,只是改动我定义的宏就可以了。

堆栈

#define print_oprt(op)

递归

#define move(disk,src,dst)

表示这个打印操作什么都不做。

下面是我在我的计算机上虚拟的Linux环境下用3种不同的方法解决规模为1-30的汉诺塔问题所花的时间的比较结果(单位是秒),你也可以把这个程序下载到你的计算机上去测试一下。

Scale   Stack   Recursion       Other (1-30)

1       0       0       0

2       0       0       0

3       0       0       0

4       0       0       0

5       0       0       0

6       0       0       0

7       0       0       0

8       0       0       0

9       0       0       0

10      0       0       0

11      0       0       0

12      0       0       0

13      0       0       0

14      0       0       0.01

15      0       0       0.01

16      0.02    0       0.01

17      0.03    0       0.03

18      0.05    0       0.05

19      0.12    0       0.12

20      0.23    0.01    0.23

21      0.49    0.01    0.47

22      0.95    0.04    0.89

23      1.92    0.07    1.87

24      3.8     0.15    3.55

25      7.65    0.3     7.52

26      15.2    0.6     14.24

27      30.49   1.2     29.7

28      61.11   2.41    57.24

29      111.15 4.29    97.56

30      201.09 7.72    184.32

用堆栈和其它的方法所花的时间比较接近,而用递归的速度却是最快的。相差非常的大。到底是什么原因呢,按理说应该不会有这么大的差别哦。

总结了一下,大概有以下原因:

1. STL本身的效率不是太高

STL功能强大了,效率上必然要受到一定的影响

2.  递归的方式函数调用比较少,就是调用它本身,而其它方式函数调用比较多

从代码中我们就可以看出,非递归方式调用函数的次数远远比递归方式多,每次移动操作都要调用好几次函数,pop,push等,而递归方式,每次移动操作只调用本身一次,故系统堆栈的负担要小的多。

3.  对堆栈实现,涉及到对象的多次构造和析构,并且还有就是堆栈的多次重新分配也需要消耗不少的时间(STL中stack是顺序存储结构,当空间不够用时,再向系统申请双倍的空间)

附录

上面提到的所以代码我都已经把它压缩好了,并且提供下载,

http://www.freewebs.com/zhengsh/download/hanoi.tar.gz

在readme文件中有比较详细的说明。除了hanoi_cmp.c其它的文件都可以在windows,linux下通过编译,我使用的是Linux下实现的,所以最好在Linux下重新编译它们。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值