c语言汉诺塔演示程序设计(基于堆栈、递归)
来源:互联网 发布:iope神仙水怎么用 知乎 编辑:程序博客网 时间:2024/04/30 05:53
第二个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;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语言完成。希望多多交流,学习。
- 堆栈详解(c语言)
- 【C语言】递归 - 汉诺塔
- 基于ARM的硬件启动程序设计-初始化堆栈(转载)
- 汉诺塔问题算法(c语言控制台动画演示版)
- C语言及程序设计进阶例程-5 认识递归
- 《C语言及程序设计》程序阅读——递归函数
- 《C语言及程序设计》实践项目——递归函数
- 《C语言及程序设计》实践参考——递归函数
- C语言及程序设计实践项目-递归和多文件组织
- C语言经典-----汉诺塔(递归)
- 西卡C语言汉诺塔演示程序
- 简单堆栈实现(C语言)
- 堆栈实现迷宫出路(C语言)
- 堆栈的实现(c语言)
- 第17周项目2--去除str中的特定字符c(空格),结果保存到原字符串中(用指针做形参)
- java多线程试题
- Div Popup fix the page content height
- 创建 Delphi DataSnap 程序的问题集萃(1)
- 学习压缩感知及稀疏表示之入门
- c语言汉诺塔演示程序设计(基于堆栈、递归)
- JVM学习(2)
- 获取app运行次数运行时间等信息
- 第17周项目3--求字符串str的长度并返回(用数组名做形参)
- tomcat根据域名绑定一个工程
- 调试PHP程序利用浏览器的Javascript控制台
- 长沙南雅中学一新生发言稿
- typeid 与 typeinfo 与typename
- JVM学习笔记(3)------内存管理和垃圾回收