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();
        }           
    }
}


 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值