彻底搞定汉诺塔_C程序-2015
彻底搞定汉诺塔C 程序
要深刻理解汉诺塔C 程序,首先要有以下三点认识:
1 、函数一经定义,其形参位置和数据类型就被确定下来,在后续调用的过程中,形参的位置是不会改变的。
2 、形参在调用过程中虽然位置不变,但是可以被赋予不同的值。
3 、在再入调用时,函数参数列表中所赋予的值是实参值,首次调用该函数时对应形参被赋予了什么样的实参,那么再
入调用时该实参将被赋予到再入函数参数列表中的对应形参名下(注意:是形参名,不是形参,在任何一次调用中,形
参位置是不会改变的,形参名只代表了在调用过程中应赋予什么样的实参值,而不是说形参位置发生了变动)
有了上述认知,我们就可以深入讨论汉诺塔函数的执行过程了:
问题描述:
设a, b, c 是3 个塔座。在塔座a 上有n 个圆盘, 这些圆盘自下而上, 由大到小的叠放。要求将a 上的圆盘移到c 上, 并仍
按同样顺序叠放。移动圆盘应遵守以下规则:
规则1:每次只能移动1 个圆盘
规则2 :任何时刻都不允许将大圆盘压在小圆盘之上
规则3 :在满足规则1 和2 的前提下, 可将圆盘移至任一塔座上
n 个圆盘的移动方法:
上面(n-1)个圆盘
n个圆盘分为2部分
最下面的第n号圆盘
移动步骤:
① (n-1)个圆盘a◊b (要达成这个目标,我们需要通过多次调用再入函数移动盘子来实现)
② 第n 个圆盘a◊c (达成上面n-1 个盘子的移动以后,再移动第n 个盘子)
③ (n-1)个圆盘b◊c (要达成这个目标,我们同样需要通过多次调用再入函数移动盘子来实现)
对应程序:
void Hanio(int n, char a, char b, char c) // 将n 个盘子借助b 塔座从a 塔座移到c 塔座
{ if (n==1) Move(n, a, c); // 如果只需要移动1 个盘子则直接将这个盘子从a 移到c
else //否则
{ Hanio(n-1, a, c, b); // 将n-1 个盘子借助c 从a 移到b
Move(n, a, c); // 将第n 个盘子从a 移到c
Hanio(n-1, b, a, c); // 将n-1 个盘子借助a 从b 移到c
}
}
下面我们以n=3 ,展开来说明具体过程(设A 、B 、C 分别为对应地插在a、b 、c 塔座(形参)上的柱子(实参) :
Hanio( 3, A, B, C) // 将3 个盘子借助位于b 塔座上的B 柱从位于a 塔座上的A 柱上移到位于c 塔座上的C 柱上
{ if (n==1)
Move(n, A, C); // 如果只需要移动1 个盘子则直接将这个盘子从位于a 塔座上的A 柱上移到位于c 塔座上的C 柱上
else //否则
{ Hanio(2, A, C, B); // 将上部2 个盘子借助位于b 塔座上的C 柱从位于a 塔座上的A 柱上移到位于c 塔座上的B 柱上
Move(3, A, C); //将A 柱上的第3 个盘子移到C 柱上
Hanio(2, B, A, C); // 将位于a 塔座上的B 柱上的2 个盘子借助位于b 塔座上的A 柱移到位于c 塔座上的C 柱上
}
}
上述程序中:
Hanio(2, A, C, B); 是实现将上部2 个盘子借助位于b 塔座上的C 柱从位于a 塔座上的A 柱上移到位于c 塔座上的B 柱上的
展开实现过程如下:
Hanio( 2, A, C, B) // 将上部2 个盘子借助位于b 塔座上的C 柱从位于a 塔座上的A 柱上移到位于c 塔座上的B 柱上
{ if (n==1)
Move(n, A, B); // 如果只需要移动1 个盘子则直接将这个盘子从位于a 塔座上的A 柱上移到位于c 塔座上的B 柱上
else //否则
{ Hanio(1, A, B, C); // 将最上面1 个盘子借助位于b 塔座上的B 柱从位于a 塔座上的A 柱上移到位于c 塔座上的C 柱上
Move(2, A, B); // 将A 柱上的第2 个盘子移到B 柱上
Hanio(1, C