汉诺塔算法

一个印度传说:在一个神庙里有有一个汉诺塔,就是一个铜板上插着3个宝石针,其中一根针从上到下的穿着由小到大的铜片64片,僧人们一次只能移动一个铜片,并且不论移到哪个针上,必须保持小片在大片上面。僧侣们预言,当所有的铜片都从穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消亡。

当然,这只是个传说,如果每秒钟移动一次,那么移完这个汉诺塔将耗费大约 5845亿年,到那时说不定又有新的星系被人类发现了。

汉诺塔算法可以根据推理得出:

public class HanioDemo
{
    //把第几个盘子从哪个杆子上移动到哪个杆子上
    private void Move(int iNum, char cSource, char cDest)
    {   
        Console.WriteLine("把第{0}个盘子从杆子{1}上移动到杆子{2}上", iNum, cSource, cDest);
    }

    //移动第几个盘,从第几个杆子到第几个杆子
    public void Hanoi(int n, char cSource, char cTemp, char cDest)
    {
        if (1 == n)
        {
            Move(1, cSource, cDest);
        }
        else if (2 == n)
        {
            //2个盘的汉诺塔也可以归纳为

            //经过第三次改造,抽象,发现n==2的情况和n==3的情况完全一样
            //所以,继续改造,第四次了。

            //Hanoi(1, cSource, cDest, cTemp);
            Hanoi(n - 1, cSource, cDest, cTemp);

            //Move(1, cSource, cTemp);

            //Move(2, cSource, cDest);
            Move(n, cSource, cDest);

            //Hanoi(1, cTemp, cSource, cDest);
            Hanoi(n - 1, cTemp, cSource, cDest);

            //Move(1, cTemp, cDest);
        }
        else if (3 < n)
        {
            /*
            Move(1, cSource, cDest);
            Move(2, cSource, cTemp);
            Move(1, cDest, cTemp);*/
            //归纳:前三步移动可以归结为2个汉诺塔的移动
            //Hanoi(2, cSource, cDest, cTemp);

            //第三次修改,将具体数字用n表示,再次抽象!
            Hanoi(n - 1, cSource, cDest, cTemp);
            //Move(3, cSource, cDest);
            Move(n, cSource, cDest);

            //Hanoi(2, cTemp, cSource, cDest);
            Hanoi(n - 1, cTemp, cSource, cDest);

            //后三步也很像2个汉诺塔移动
            /*
            Move(1, cTemp, cSource);
            Move(2, cTemp, cDest);
            Move(1, cSource, cDest);*/
        }    
    }
}

最终抽象出来的方法:

/// <summary>
/// 汉诺塔抽象出的最终方法
/// </summary>
/// <param name="n">盘子的个数</param>
/// <param name="cSource">第一个杆子</param>
/// <param name="cTemp">第二个杆子</param>
/// <param name="cDest">第三个杆子</param>
public void HanoiDone(int n, char cSource, char cTemp, char cDest)
{
    if (n < 1)
    {
        Console.WriteLine("盘子的数量必须是自然数!");
        return;
    }
    else if(1==n)
    {
        Move(1, cSource, cDest);
    }
    else
    {
        HanoiDone(n - 1, cSource, cDest, cTemp);
        Move(n, cSource, cDest);
        HanoiDone(n - 1, cTemp, cSource, cDest);
    }
}

 

posted on 2013-04-06 22:19  Frank.Fan  阅读(656)  评论(0编辑  收藏  举报