递归思想非常简单也是最常见的算法之一,其中一代表例题就是汉诺塔问题。
解题的算法很简单:
void Hanoi(int n,int A,int B,int C)
{
if(n>0)
{
Hanoi(n-1,a,c,b);
move(a,b);
show();
Hanoi(n-1,c,b,a);
}
}
在此之上,建立一个简单的堆栈用于模拟塔柱与圆盘的放入取出动作。再使用一个显示函数将堆栈数据结构转换为简单的图形,在每次移动圆盘时显示一遍,形成了一个简单的动画效果。
//文件:Hanoi.c
//功能:汉诺塔问题算法的控制台动画演示程序
//运行:使用c编译器编译运行(已经通过MinGW版的gcc编译运行测试)
//作者:miao
//时间:2010-3-23
#include
#define MAX 5 //塔的最大高度(层数),也是圆盘的最大个数与最大大小
//一个堆栈,用于模拟塔柱
struct stack
{
int space[MAX];//堆栈空间,用于塔柱的各层,存放的数字代表圆盘的大小
int p;//栈顶指针
}stacks[3];//三个塔柱
char star[MAX+1]; //存放星星的数组(用于表示圆盘)
char space[MAX+1];//存放空格的数组
//入栈,表示放入一个圆盘:stackNum:塔号,number:圆盘大小
void push(stackNum,number)
{
if(stacks[stackNum].p>=MAX)
{
printf("错误:无法入栈,已到达栈顶。/n");
exit(0);
}
stacks[stackNum].space[stacks[stackNum].p++]=number;
}
//出栈,表示取出一个圆盘:sstackNum:塔号,return::圆盘大小
int pop(stackNum)
{
if(stacks[stackNum].p<=0)
{
printf("错误:无法出栈,已到达栈底。/n");
exit(0);
}
return stacks[stackNum].space[--stacks[stackNum].p];
}
//显示当前塔的状态
void show()
{
int charCount;//统计当前行绘制了多少个字符
int i,j;
system("cls");//清屏函数
//最高层开始逐层绘制塔图
int taP= MAX;
while(taP--)
{
for(i=0;i<3;i++)
{
charCount = 0;
//若此层有圆饼,就绘制
if(taP<=stacks[i].p-1)
{
printf("%s",&star[MAX-stacks[i].space[taP]]);
charCount+=stacks[i].space[taP];
}
//补全空格
printf("%s|",&space[charCount]);
}
printf("/n");
}
sleep(500);
}
//移动圆饼:柱a->柱b
void move(int a,int b)
{
push(b,pop(a));
}
//汉诺塔主算法:n:圆饼数,a~c:三个塔柱
void Hanoi(int n,int a,int b,int c)
{
if(n>0)
{
Hanoi(n-1,a,c,b);
move(a,b); //移动圆饼
show(); //显示汉诺塔
Hanoi(n-1,c,b,a);
}
}
//初始化一些变量
void init()
{
stacks[0].p = stacks[1].p = stacks[2].p =0;
int i;
for(i=0;i
{
star[i]='*'; //创建一个星星数组,便于绘图
space[i]=' '; //创建一个空格数组,便于绘图
}
space[i]=star[i]='/0';
}
int main()
{
init();
//放置圆饼:放入零号塔柱,依次放入大小为5~1的圆饼
push(0,5);
push(0,4);
push(0,3);
push(0,2);
push(0,1);
show(); //显示放入圆饼后的汉诺塔
Hanoi(5,0,1,2);//执行汉诺塔算法
return 0;
}