c语言汉诺塔演示程序设计(基于堆栈、递归)
2013-12-24 12:44
471 查看
第二个c语言课程设计,看到这个题目的时候有些迷茫,没有头绪,但是在网上看到了一个实现的范例之后,有了些思路,第一次写的时候结果总是按照之前看的范例的思路,但又不能领会他人思路的精髓,始终不得要领。
昨天决定自己按照自己的思路,自己设计数据结构,实现目标,晚上在床上构思了十来分钟。今早起床根据昨晚的构思两个小时左右就写完了整个小程序,主要源于思路清晰,且程序本身内容不多,主要是关于堆栈数据结构的运用和递归思想的实践,总共不到200行.
//C语言写的汉诺塔(10层以下)动画演示小程序
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>
#include<Windows.h>
#include<malloc.h>
//宏定义9层汉诺塔
#define LEN 9
//每个柱子的结构
typedef>int>int>int>COORD>
//每一个element对应一个pos值,坐标
}stack,*pstack;
//函数声明
void InitStack(pstack ,int );
void Push(pstack ,int );
int Pop(pstack );
void PrintStack(pstack );
void Hanoi(pstack ,pstack ,pstack ,int );
void> //记录汉诺塔移动步数
int>//设置内部变量
int i;
HANDLE hOutput;
COORD pos;
stack st[3];
pstack a,b,c;
a = st;
b = st+1;
c = st+2;
//初始化三个栈为空, 且初始化栈元素显示坐标的x值
InitStack(a,5);
InitStack(b,15);
InitStack(c,25);
//给a栈赋初值,栈低到栈顶依次为9-1
for(i=1;i<=LEN;i++)
{
Push(a,10-i);
}
//显示三个柱子初始情况
PrintStack(a);
PrintStack(b);
PrintStack(c);
pos.X = 1;
pos.Y = 9;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOutput,pos);
printf(" A B C");
//开始汉诺塔移动
pos.X = 5;
pos.Y = 11;
SetConsoleCursorPosition(hOutput,pos);
printf("输入移动的汉诺塔层数:");
scanf("%d",&i);
getchar();
//屏蔽输入
Hanoi(a,b,c,i);
//把a的i层通过b移动到c
return 0;
}
//初始化函数,初始化内容:栈长、栈顶指针、栈元素显示位置
void InitStack(pstack ps,int x)
{
int i;
ps->max = LEN;
ps->top = -1;
for(i=0;i<LEN;i++)
{
ps->pos[LEN-1-i].X = x;
ps->pos[LEN-1-i].Y = i;
}
}
//将x压入栈sp
void Push(pstack sp,int x)
{
if(>
{
printf("ERROR!the stack is full,can't push!\n");
getchar();
return;
}
else
{
sp->top++;
sp->element[sp->top] = x;
}
}
//将栈sp栈顶元素出栈返回
int Pop(pstack sp)
{
if(sp->top >= 0)
{
return sp->element[sp->top--];
}
else
{
printf("ERROR!the stack is empty,can't pop!\n");
getchar();
return -1;
}
}
//按照堆栈显示位置打印堆栈
void PrintStack(pstack sp)
{
int i;
HANDLE hOutput;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
for(i=0;i<=sp->top;i++)
{
SetConsoleCursorPosition(hOutput,sp->pos[i]);
printf("%d",sp->element[i]);
}
}
//汉诺塔递归移动过程
void Hanoi(pstack x,pstack y,pstack z,int i)
{
if(i == 1)
{
move(x,z,x,y,z);
}
if(i == 2)
{
move(x,y,x,y,z);
move(x,z,x,y,z);
move(y,z,x,y,z);
}
else
{
Hanoi(x,z,y,i-1);
move(x,z,x,y,z);
Hanoi(y,x,z,i-1);
}
}
//每一次移动的操作
void move(pstack j,pstack k,pstack a,pstack b,pstack c)
{
HANDLE hOutput;
COORD pos;
pos.X = 3;
pos.Y = 12;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
Push(k,Pop(j));
step++;
//显示三个柱子移动后的情况
PrintStack(a);
PrintStack(b);
PrintStack(c);
pos.X = 1;
pos.Y = 9;
SetConsoleCursorPosition(hOutput,pos);
printf(" A B C");
pos.X = 5;
pos.Y = 12;
SetConsoleCursorPosition(hOutput,pos);
printf("当前移动的步数为:%d \n",step);
getchar();
system("CLS");
}
总结:
1、对于数据结构的选择,我采用的是浪费些许空间,建立栈的元素为静态数组。也有的实现使用动态数组,虽然节省了空间,但是算法较为繁琐,
//定义栈
typedef struct
{
ElementType *pbuffer;
int max;
int top;
}Stack;
测试证明:确实不用设置p_a、p_b、p_c三个参数,这样设置函数即可(代码中的设计设想上防止hanoi函数会置换move中的输出,但是事实上因为move中的输出每个堆栈都有自己的pos元素固定位置,所以不会影响柱子输出格式)
void Hanoi(pstack ,pstack ,pstack ,int );void move(pstack ,pstack ,pstack ,pstack ,pstack );
昨天决定自己按照自己的思路,自己设计数据结构,实现目标,晚上在床上构思了十来分钟。今早起床根据昨晚的构思两个小时左右就写完了整个小程序,主要源于思路清晰,且程序本身内容不多,主要是关于堆栈数据结构的运用和递归思想的实践,总共不到200行.
//C语言写的汉诺塔(10层以下)动画演示小程序
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>
#include<Windows.h>
#include<malloc.h>
//宏定义9层汉诺塔
#define LEN 9
//每个柱子的结构
typedef>int>int>int>COORD>
//每一个element对应一个pos值,坐标
}stack,*pstack;
//函数声明
void InitStack(pstack ,int );
void Push(pstack ,int );
int Pop(pstack );
void PrintStack(pstack );
void Hanoi(pstack ,pstack ,pstack ,int );
void> //记录汉诺塔移动步数
int>//设置内部变量
int i;
HANDLE hOutput;
COORD pos;
stack st[3];
pstack a,b,c;
a = st;
b = st+1;
c = st+2;
//初始化三个栈为空, 且初始化栈元素显示坐标的x值
InitStack(a,5);
InitStack(b,15);
InitStack(c,25);
//给a栈赋初值,栈低到栈顶依次为9-1
for(i=1;i<=LEN;i++)
{
Push(a,10-i);
}
//显示三个柱子初始情况
PrintStack(a);
PrintStack(b);
PrintStack(c);
pos.X = 1;
pos.Y = 9;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOutput,pos);
printf(" A B C");
//开始汉诺塔移动
pos.X = 5;
pos.Y = 11;
SetConsoleCursorPosition(hOutput,pos);
printf("输入移动的汉诺塔层数:");
scanf("%d",&i);
getchar();
//屏蔽输入
Hanoi(a,b,c,i);
//把a的i层通过b移动到c
return 0;
}
//初始化函数,初始化内容:栈长、栈顶指针、栈元素显示位置
void InitStack(pstack ps,int x)
{
int i;
ps->max = LEN;
ps->top = -1;
for(i=0;i<LEN;i++)
{
ps->pos[LEN-1-i].X = x;
ps->pos[LEN-1-i].Y = i;
}
}
//将x压入栈sp
void Push(pstack sp,int x)
{
if(>
{
printf("ERROR!the stack is full,can't push!\n");
getchar();
return;
}
else
{
sp->top++;
sp->element[sp->top] = x;
}
}
//将栈sp栈顶元素出栈返回
int Pop(pstack sp)
{
if(sp->top >= 0)
{
return sp->element[sp->top--];
}
else
{
printf("ERROR!the stack is empty,can't pop!\n");
getchar();
return -1;
}
}
//按照堆栈显示位置打印堆栈
void PrintStack(pstack sp)
{
int i;
HANDLE hOutput;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
for(i=0;i<=sp->top;i++)
{
SetConsoleCursorPosition(hOutput,sp->pos[i]);
printf("%d",sp->element[i]);
}
}
//汉诺塔递归移动过程
void Hanoi(pstack x,pstack y,pstack z,int i)
{
if(i == 1)
{
move(x,z,x,y,z);
}
if(i == 2)
{
move(x,y,x,y,z);
move(x,z,x,y,z);
move(y,z,x,y,z);
}
else
{
Hanoi(x,z,y,i-1);
move(x,z,x,y,z);
Hanoi(y,x,z,i-1);
}
}
//每一次移动的操作
void move(pstack j,pstack k,pstack a,pstack b,pstack c)
{
HANDLE hOutput;
COORD pos;
pos.X = 3;
pos.Y = 12;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
Push(k,Pop(j));
step++;
//显示三个柱子移动后的情况
PrintStack(a);
PrintStack(b);
PrintStack(c);
pos.X = 1;
pos.Y = 9;
SetConsoleCursorPosition(hOutput,pos);
printf(" A B C");
pos.X = 5;
pos.Y = 12;
SetConsoleCursorPosition(hOutput,pos);
printf("当前移动的步数为:%d \n",step);
getchar();
system("CLS");
}
总结:
1、对于数据结构的选择,我采用的是浪费些许空间,建立栈的元素为静态数组。也有的实现使用动态数组,虽然节省了空间,但是算法较为繁琐,
//定义栈
typedef struct
{
ElementType *pbuffer;
int max;
int top;
}Stack;
typedef struct { Stack * sp[3]; int x[3]; int y; int total; }Hannuota;
测试证明:确实不用设置p_a、p_b、p_c三个参数,这样设置函数即可(代码中的设计设想上防止hanoi函数会置换move中的输出,但是事实上因为move中的输出每个堆栈都有自己的pos元素固定位置,所以不会影响柱子输出格式)
void Hanoi(pstack ,pstack ,pstack ,int );void move(pstack ,pstack ,pstack ,pstack ,pstack );
相关文章推荐
- 九层汉诺塔递归和非递归模拟演示(C语言)
- 汉诺塔:非递归,非堆栈,使用C语言完成。希望多多交流,学习。
- C语言及程序设计进阶例程-7 递归经典:汉诺塔
- C语言 N阶汉诺塔问题的递归实现
- C语言练习 (典型递归问题)汉诺塔问题
- <C语言>递归思维及其实现-----汉诺塔问题
- C语言数据结构----递归的应用(斐波拉契数列、汉诺塔、strlen的递归算法)
- 【数据结构与算法】汉诺塔算法——C语言递归实现
- C语言进阶-7讲: 递归经典:汉诺塔
- C语言经典算法(十)——递归实现汉诺塔
- 汉诺塔问题的递归解法与非递归解法(堆栈解法)
- 用C语言解决(hanoi)汉诺塔问题——函数的递归调用
- 基于ARM的硬件启动程序设计-初始化堆栈(转载)
- 基于ARM的硬件启动程序设计-初始化堆栈
- 基于MFC单文档的汉诺塔动画演示程序,手动输入盘子数
- 黑马程序员--汉诺塔问题的递归求解C语言
- python算法和数据结构笔记--汉诺塔问题超详细递归过程图解(堆栈数据结构)