C#解决汉诺塔问题DEMO

作者:junjie 时间:2023-03-25 19:11:25 

汉诺塔问题是学习递归的入门问题,这里用C#简单实现了一个汉诺塔之间传递盘子的小程序

C#解决汉诺塔问题DEMO

通过简单绘图实现盘子在几个塔之间的转换:


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
  • asp之家 软件编程 m.aspxhome.com