C#解决汉诺塔问题DEMO
作者:junjie 时间:2023-03-25 19:11:25
汉诺塔问题是学习递归的入门问题,这里用C#简单实现了一个汉诺塔之间传递盘子的小程序
通过简单绘图实现盘子在几个塔之间的转换:
namespace 汉诺塔
{
//盘子类
class HanioItem
{
public int HanoiItemHeight { get; set; }//盘子的高度
public int HanoiItemWidth { get; set; }//盘子的宽度
public Point HanoiItemPoint { get; set; }//画盘子的起始点
}
}
namespace 汉诺塔
{
public partial class FrmShow : Form
{
List<HanioItem> HanioItemsA = new List<HanioItem>();//塔A中的盘子集合
List<HanioItem> HanioItemsB = new List<HanioItem>();//塔B中的盘子集合
List<HanioItem> HanioItemsC = new List<HanioItem>();//塔C中的盘子集合
Pen p;//画笔
Graphics hanioPicA;//塔A的画布
Graphics hanioPicB;//塔B的画布
Graphics hanioPicC;//塔C的画布
int tag;//盘子个数
public FrmShow()
{
InitializeComponent();
}
/// <summary>
/// 初始化3个PictureBox画布
/// </summary>
public void InitialTools()
{
p = new Pen(Color.Black);
hanioPicA = HanoiPicA.CreateGraphics();
hanioPicB = HanoiPicB.CreateGraphics();
hanioPicC = HanoiPicC.CreateGraphics();
}
public void InitialGraphics()
{
int HanioItemHeight = 15;//塔中盘子的高度
int HanioStartItemWidth = 90;//第一个盘子的宽
Point HanioStartItemP = new Point(15, 135);//第一个盘子起始点
InitialTools();
tag = Convert.ToInt16(this.Tag.ToString());
HanioItemsA.Clear();
HanioItemsB.Clear();
HanioItemsC.Clear();
//初始化塔A上的盘子
int diffrence = (90 - 30) / tag;//两个盘子之间宽度之差
for (int i = 1; i <= tag; i++)
{
HanioItem item = new HanioItem();
item.HanoiItemWidth = HanioStartItemWidth;
item.HanoiItemHeight = HanioItemHeight;
item.HanoiItemPoint = HanioStartItemP;
HanioItemsA.Add(item);
HanioStartItemWidth -= diffrence;
HanioStartItemP.X += diffrence / 2;
}
//为汉诺塔画盘子
ShowHanoiGraphics();
}
/// <summary>
/// 画3个塔中的盘子
/// </summary>
private void ShowHanoiGraphics()
{
hanioPicA.Clear(this.BackColor);
hanioPicB.Clear(this.BackColor);
hanioPicC.Clear(this.BackColor);
//为汉诺塔A画初始线条
hanioPicA.DrawLine(p, 0, 150, 120, 150);
hanioPicA.DrawLine(p, 60, 0, 60, 150);
//为汉诺塔B画初始线条
hanioPicB.DrawLine(p, 0, 150, 120, 150);
hanioPicB.DrawLine(p, 60, 0, 60, 150);
//为汉诺塔C画初始线条
hanioPicC.DrawLine(p, 0, 150, 120, 150);
hanioPicC.DrawLine(p, 60, 0, 60, 150);
//画A塔的盘子
for (int i = 0; i < HanioItemsA.Count; i++)
{
hanioPicA.DrawRectangle(p, HanioItemsA[i].HanoiItemPoint.X, HanioItemsA[i].HanoiItemPoint.Y - i * 15, HanioItemsA[i].HanoiItemWidth, HanioItemsA[i].HanoiItemHeight);
}
//画B塔的盘子
for (int i = 0; i < HanioItemsB.Count; i++)
{
hanioPicB.DrawRectangle(p, HanioItemsB[i].HanoiItemPoint.X, HanioItemsB[i].HanoiItemPoint.Y - i * 15, HanioItemsB[i].HanoiItemWidth, HanioItemsB[i].HanoiItemHeight);
}
//画C塔的盘子
for (int i = 0; i < HanioItemsC.Count; i++)
{
hanioPicC.DrawRectangle(p, HanioItemsC[i].HanoiItemPoint.X, HanioItemsC[i].HanoiItemPoint.Y - i * 15, HanioItemsC[i].HanoiItemWidth, HanioItemsC[i].HanoiItemHeight);
}
}
/// <summary>
/// 汉诺塔核心递归函数
/// </summary>
/// <param name="n">盘子个数</param>
/// <param name="A">塔A</param>
/// <param name="B">塔B</param>
/// <param name="C">塔C</param>
private void Hanio(int n, List<HanioItem> A, List<HanioItem> B, List<HanioItem> C)
{
if (n == 1)
{
HanioMove(A, C);
}
else
{
Hanio(n - 1, A, C, B);
HanioMove(A, C);
Hanio(n-1,B,A,C);
}
}
/// <summary>
/// 盘子移动画图实现
/// </summary>
private void HanioMove(List<HanioItem> X, List<HanioItem> Y)
{
HanioItem item = new HanioItem();
item = X[X.Count-1];
X.Remove(item);//塔X移除一个盘子
Y.Add(item); //塔Y添加一个盘子
ShowHanoiGraphics();
System.Threading.Thread.Sleep(1000);
}
private void btnOK_Click(object sender, EventArgs e)
{
Hanio(tag, HanioItemsA, HanioItemsB, HanioItemsC);
}
private void FrmShow_Paint(object sender, PaintEventArgs e)
{
InitialGraphics();
}
}
}
标签:C#,汉诺塔
0
投稿
猜你喜欢
关于Java中增强for循环使用的注意事项
2021-08-09 16:47:43
c# 多线程处理多个数据的方法
2023-12-01 17:45:58
Springboot如何根据实体类生成数据库表
2023-11-20 13:54:39
Android 实现自定义圆形listview功能的实例代码
2022-06-20 06:58:29
Android ViewPager2 使用及自定义指示器视图实现
2022-06-16 09:35:26
让Java后台MySQL数据库能够支持emoji表情的方法
2022-12-30 04:24:45
Android 基于百度语音的语音交互功能(推荐)
2021-08-22 01:26:38
C#身份证验证小例子
2022-06-22 05:22:01
区分Java中的ArrayList和LinkedList
2021-05-26 11:09:55
史上最强C语言分支和循环教程详解
2022-07-01 07:59:35
Android中的Selector的用法详解及实例
2023-11-26 22:17:06
一篇文章带你了解java接口与继承
2022-07-15 02:44:08
Intellij IDEA导入JAVA项目并启动(图文教程)
2021-11-05 12:30:18
Springboot集成Elasticsearch的步骤与相关功能
2022-07-23 06:47:30
使用Jitpack发布开源Java库的详细流程
2021-12-18 06:55:58
详解Android USB转串口通信开发基本流程
2022-01-04 10:12:15
struts2拦截器_动力节点Java学院整理
2023-06-11 10:11:36
详解Android Activity之间跳转出现短暂黑屏的处理方法
2021-06-28 04:44:03
SpringBoot项目中处理返回json的null值(springboot项目为例)
2023-10-26 04:49:06
java文件下载代码实例(单文件下载和多文件打包下载)
2023-02-16 00:38:37