C#解决汉诺塔问题DEMO
作者:junjie 发布时间:2023-03-25 19:11:25
标签:C#,汉诺塔
汉诺塔问题是学习递归的入门问题,这里用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();
}
}
}


猜你喜欢
- 本文实例讲述了Android编程实现拍照功能的2种方法。分享给大家供大家参考,具体如下:Android系统的照相功能,已实现2种方法,可供大
- 这两天实现了下新手引导需要的遮罩镂空shader效果,记录一下。1、圆形镂空shader代码:  
- Command 常用属性CommText 要下达至数据源的命令CommanTimeout 出错等待时间Command 三种方法Execute
- 父类空间优先于子类对象产生在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空间,便可以包含
- 当用eclipse 导入一个已经存在的项目时,经常会遇见:Unable to resolve target 'android-XX&
- 在Android上,不止一个途径来侦听用户和应用程序之间交互的事件。对于用户界面里的事件,侦听方法就是从与用户交互的特定视图对象截获这些事件
- 补充使用Spring Cloud Config加密功能需要下载JCE扩展,用于生成无限长度的密文。链接:http://www.oracle.
- 先看看代码再说:package com.b510.note; import java.math.BigInteger;
- 本文实例为大家分享了Java实现简单的飞机大战游戏,控制主飞机的具体代码,供大家参考,具体内容如下接着上一篇:Java实现简单的飞机大战游戏
- Springmvc调用存储过程,并返回存储过程返还的数据java后端很多时候都需要和数据库进行交互,并返回业务数据。一般情况下都会采用执行S
- 1.内部类概念及分类将一个类定义在另一个类的内部或者接口内部或者方法体内部,这个类就被称为内部类,我们不妨将内部类所在的类称为外围类,除了定
- github开源项目(Zxing)demo最快的调用Zxing方法1.关联第三方库2.调用基础的扫码3.获取返回值具体代码如下://1.默认
- springboot重定向外部网页package com.liangxs.web;import java.io.IOException;im
- 简介TCP简介TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层
- 1. 什么是RESTREST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状
- 本文实例讲述了C#通过创建Windows服务启动程序的方法。分享给大家供大家参考,具体如下:1. 新建一个Windows服务应用程序创建项目
- 关于隐藏和覆盖的区别,要提到RTTI(run-time type identification)(运行期类型检查),也就是运行期的多态,当一
- 1. 定义TreeMap的排序方法使用Comparator对象作为参数需要注意的是:排序方法是针对键的,而不是值的。如果想针对值,需要更麻烦
- 在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Ap
- 大家好,我是指北君。Java的 record 关键字是Java 14中引入的一个新的语义特性。record 对于创建小型不可变的对象非常有用