汉诺塔采用的是一个经典递归算法,以前我在学《数据结构》时涉及过,前不久公司组织拓展活动,活动期间有一项就是移动汉诺塔,因此活动结束后我重新设计并实现了这一算法。其中和书中讲的略有区别,但大同小异,以记后来。

1 头文件声明

// 一个汉诺塔
struct stOneHLT{
    stOneHLT()
    {
        HLTName = "";
        SourceNums = 0;
        Numslist.clear();
        //pUpHLT = NULL;

}
    stOneHLT(const stOneHLT& otherOneHLT)
    {
        if (this != &otherOneHLT)
        {
            Numslist.clear();
            list<int>::const_iterator it = otherOneHLT.Numslist.begin();
            while (it != otherOneHLT.Numslist.cend())
            {
                Numslist.push_back(*it);
                it++;
            }

HLTName = otherOneHLT.HLTName;
            SourceNums = otherOneHLT.SourceNums;

}
    }
    stOneHLT operator = (const stOneHLT& otherOneHLT)
    {
        if (this != &otherOneHLT)
        {
            Numslist.clear();
            list<int>::const_iterator it = otherOneHLT.Numslist.begin();
            while (it != otherOneHLT.Numslist.cend())
            {
                Numslist.push_back(*it);
                it++;
            }

HLTName = otherOneHLT.HLTName;
            SourceNums = otherOneHLT.SourceNums;

}
        return *this;
    }
    CString HLTName; // 汉诺塔名
    int SourceNums; // 原始所有层级
    list<int> Numslist; // 当前塔的所有盘子
    //stOneHLT* pUpHLT;
};

// 汉诺塔
class CHLT{
public:
    CHLT(int cj,CListBox* pListBox);

protected:

// 判断移动方向,moveLeve:为待移动的层级
    stOneHLT& CheckMoveDirection(int moveLeve, stOneHLT& sourceOneHLT, stOneHLT& tmpOneHLT, stOneHLT& TargetOneHLT);
    
    void Move4(stOneHLT& sourceOneHLT, stOneHLT& tmpOneHLT, stOneHLT& TargetOneHLT, int movenum);

stOneHLT& FindHLT(int findValue, stOneHLT& sourceOneHLT, stOneHLT& tmpOneHLT, stOneHLT& TargetOneHLT);

void showMove(int i, stOneHLT& sourceOneHLT, stOneHLT& TargetOneHLT);

public:
    
    void beginMove();

private:
    stOneHLT AOneHLT; // A汉诺塔
    stOneHLT BOneHLT; // B汉诺塔
    stOneHLT COneHLT; // C汉诺塔
    int m_MoveNums; // 移动的次数
    stOneHLT* PrevHLT;
    CListBox* m_pListBox; // 
};

2 实现文件

//----------------------------------CHLT begin------------------------------------------------------

CHLT::CHLT(int cj,CListBox* pListBox)
{
    AOneHLT.HLTName = _T("A");
    BOneHLT.HLTName = _T("B");
    COneHLT.HLTName = _T("C");
    m_pListBox = pListBox;

for (int i = 0; i < cj; i++)
    {
        AOneHLT.Numslist.push_back(i + 1);
    }
    AOneHLT.SourceNums = AOneHLT.Numslist.size();
    BOneHLT.Numslist.clear();
    COneHLT.Numslist.clear();
    PrevHLT = NULL;
    m_MoveNums = 0;
}

stOneHLT& CHLT::FindHLT(int findValue, stOneHLT& sourceOneHLT, stOneHLT& tmpOneHLT, stOneHLT& TargetOneHLT)
{
    list<int>::iterator it = sourceOneHLT.Numslist.begin();
    while ( it != sourceOneHLT.Numslist.end() )
    {
        if (findValue == *it)
        {
            return sourceOneHLT;
        }
        it++;
    }

it = tmpOneHLT.Numslist.begin();
    while (it != tmpOneHLT.Numslist.end())
    {
        if (findValue == *it)
        {
            return tmpOneHLT;
        }
        it++;
    }

it = TargetOneHLT.Numslist.begin();
    while (it != TargetOneHLT.Numslist.end())
    {
        if (findValue == *it)
        {
            return TargetOneHLT;
        }
        it++;
    }

}

void CHLT::showMove(int i, stOneHLT& sourceOneHLT, stOneHLT& TargetOneHLT)
{
    m_MoveNums++;
    CString msg;
    msg.Format(_T("%d %s->%s"), i, sourceOneHLT.HLTName.GetBuffer(), TargetOneHLT.HLTName.GetBuffer());
    sourceOneHLT.HLTName.ReleaseBuffer();
    TargetOneHLT.HLTName.ReleaseBuffer();
    CString tmp = msg;

//msg.Format(_T("第%d层"), i, sourceOneHLT.HLTName.GetBuffer(), TargetOneHLT.HLTName.GetBuffer());

OutputDebugString(msg.GetBuffer());
    if (m_pListBox)
    {
        m_pListBox->AddString((LPCTSTR)tmp.GetBuffer());
        tmp.ReleaseBuffer();
    }

}

void CHLT::Move4(stOneHLT& sourceOneHLT, stOneHLT& tmpOneHLT, stOneHLT& TargetOneHLT, int movenum)
{
    for (int i = 1; i <= movenum; i++)
    {
        sourceOneHLT.SourceNums = movenum;
        stOneHLT& FindMovedHLT = CheckMoveDirection(i, sourceOneHLT, tmpOneHLT, TargetOneHLT);
        if (FindMovedHLT.Numslist.size() == 0 || i < FindMovedHLT.Numslist.front())
        {
            sourceOneHLT.Numslist.pop_front();
            FindMovedHLT.Numslist.push_front(i);

showMove(i, sourceOneHLT, FindMovedHLT);

if (i != 1)
            {
                stOneHLT& upHLT = FindHLT(i - 1, sourceOneHLT, tmpOneHLT, TargetOneHLT);
                if (sourceOneHLT.HLTName.Compare(upHLT.HLTName.GetBuffer()) != 0 && sourceOneHLT.HLTName.Compare(FindMovedHLT.HLTName.GetBuffer()) != 0)
                    Move4(upHLT, sourceOneHLT, FindMovedHLT, i - 1);  // 将辅助塔上面的当前目标塔
                else
                    if (tmpOneHLT.HLTName.Compare(upHLT.HLTName.GetBuffer()) != 0 && tmpOneHLT.HLTName.Compare(FindMovedHLT.HLTName.GetBuffer()) != 0)
                        Move4(upHLT, tmpOneHLT, FindMovedHLT, i - 1);  // 将辅助塔上面的移到当前目标塔    
                    else
                        Move4(upHLT, TargetOneHLT, FindMovedHLT, i - 1);  // 将辅助塔上面的移到当前目标塔    
                
            }
        }
        
    }
}

stOneHLT& CHLT::CheckMoveDirection(int moveLeve, stOneHLT& sourceOneHLT, stOneHLT& tmpOneHLT, stOneHLT& TargetOneHLT)
{
    int nNums = sourceOneHLT.SourceNums;
    if (nNums % 2 == 0) // 总数为双数
    {
        if (moveLeve % 2 == 0) // 
            return TargetOneHLT; // 双数层 移动到目标层
        else
            return tmpOneHLT; // 单数层移动到中间层
    }
    else // 总数为单数
    {
        if (moveLeve % 2 == 0) //  
            return tmpOneHLT; // 双数层移动到中间层
        else
            return TargetOneHLT; // 单数层移动到目标层
    }
}

void CHLT::beginMove()
{
#if 0
    Move(AOneHLT, BOneHLT, COneHLT, AOneHLT.Numslist.size());
#else
    Move4(AOneHLT, BOneHLT, COneHLT, AOneHLT.Numslist.size());
#endif
    //char msg[100] = { 0 };
    //CListBox* pListbox = (CListBox*)GetDlgItem(IDC_LIST1);
    CString msg;
    msg.Format(_T("移动的总次数:%d"), m_MoveNums);
    //sprintf_s(msg, 100, "移动的总次数:%d\n", m_MoveNums);
    //OutputDebugString(msg.GetBuffer());
    if (m_pListBox)
    {
        m_pListBox->AddString(msg.GetBuffer());
        int nCount = m_pListBox->GetCount();
        if (nCount > 0)
            m_pListBox->SetCurSel(nCount - 1);
    }
}

//----------------------------------CHLT end------------------------------------------------------

3 调用程序

在mfc的界面上放入一个按钮,在此按钮的单击事件中实现如下代码:

void CHLTDlg::OnBnClickedButton1()
{
    // TODO: Add your control notification handler code here
    UpdateData(TRUE);
    for (int i = m_pBox->GetCount() - 1; i >= 0; i--)
    {
        m_pBox->DeleteString(i);
    }
    CHLT HLT(m_nCJ, m_pBox/*pListbox*/);
    HLT.beginMove();

}

一个MFC实现的汉诺塔程序相关推荐

  1. python实现汉诺塔程序

    # 汉诺塔思想笔记# 认识汉诺塔的目标:把A柱子上的N个盘子移动到C柱子# 递归的思想就是把这个目标分解成三个子目标# 子目标1:将前n-1个盘子从a移动到b上# 子目标2:将最底下的最后一个盘子从a ...

  2. python汉诺塔运行程序_用python编写一个程序,得到汉诺塔的解决方案

    古代有一座汉诺塔,塔内有3个座A.B.C,A座上有n个盘子,盘子大小不等,大的在下,小的在上,如图所示. 有一个和尚想把这n个盘子从A座移到C座,但每次只能移动一个盘子,并且自移动过程中,3个座上的盘 ...

  3. 汉诺塔演示程序(MFC)

    首先展示一下程序演示效果: 一.程序功能: 1.可演示盘数为2-7时,移动步骤 2.点击spin按钮可增或减盘子的个数,也可在编辑框内输入数字,数字必须在3-7之间 3.可连续移动盘子,也可在中间暂停 ...

  4. linux开发汉诺塔游戏程序,汉诺塔游戏终极版

    今天,我完成了汉诺塔游戏终极版.使用一个脚本来输出汉诺塔自动运行的步骤,再通过管道提供给汉诺塔游戏,实现了自动完成汉诺塔. 在去年我用C语言写完汉诺塔游戏时,一直有个未完成的心愿.我希望能让汉诺塔自动 ...

  5. 3D屏保程序:汉诺塔

    学过程序的人一定记得汉诺塔.我们学的第一个程序是HelloWorld,而碰到的第一个坑就是汉诺塔,短短十几行代码,不知花费了多少时间精力去理解.我记得当年的开发环境还是蓝屏的,汉诺塔程序的输出还是一行 ...

  6. Ka的递归编程练习 Part4|Hanoi汉诺塔,双色汉诺塔的也有

    1 #include <stdio.h> 2 void hanoi(int s,char a,char b,char c) //a是出发盘,b是中途盘,c是结束盘 3 { 4 if(s== ...

  7. 汉诺塔递归的c语言实现(递归)

    对于递归来讲, 汉诺塔实际是经典到不能再经典的例子了,   每个数据结构的教材对会提到. 但是到最后只给出一段类似下面的一段代码: #include<stdio.h>void move(i ...

  8. c语言中的汉诺塔问题详解

    汉诺塔问题是一个古典的数学问题,也是c语言学习中一个用递归方法解题的典型实例,我们先看一下原题. 相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏.该游戏是在一块铜板装置上,有三根杆(编号A ...

  9. C语言编程求解圆盘的汉诺塔,课内资源 - 基于80x86汇编的汉诺塔

    一.软件背景介绍 我们今天要陈述的应用叫做汉诺塔,大家可能小时候都接触过类似于鲁班锁,九连环的益智玩具,我们要说的汉诺塔其实也可以说是益智玩具的一种. 下面我们具体介绍一下汉诺塔.汉诺塔有三根杆子A, ...

最新文章

  1. [PYTHON] xml.etree.ElementTree 实例
  2. Linux基础(一)----- Linux常用命令
  3. 简便方法创建自签名证书
  4. 信仰的力量—海归毕业季的选择与入职后的蜕变记
  5. python第二天 列表、元组
  6. Android学习笔记09:Paint及Canvas的简单应用
  7. AJAX from S3 CORS fails on preflight OPTIONS with 403
  8. 华为OLT(MA5680T)查看光猫光衰
  9. php.ini gd_php开启GD库实现方法
  10. 深入理解安卓Activity
  11. 小强的HTML5移动开发之路
  12. noip普及组2007 守望者的逃离
  13. Kalibr标定时卡在Extracting calibration target corners的问题
  14. 开关电源(Switch Regulator)---Buck
  15. 教程:使用tensorflow-slim训练自己数据的图像分类器
  16. CMake入门教程【核心篇】7.1项目版本号宏
  17. HDU 2197 本源串
  18. 小数乘分数怎么算过程_小数乘以分数公开课教学设计
  19. 爬虫——豆瓣电影top250
  20. bootstrap-table固定表的高度

热门文章

  1. 全国青少年软件编程等级考试标准 (预备级)
  2. 作为程序员,你的职业规划是怎样的?
  3. ios修改apn的插件_GitHub - SuPair/APN: [已废弃]适合 iOS 7 的 APN 设置工具,又一个没过审核的周末项目...
  4. 周易卦爻解读笔记——噬嗑
  5. 多个集合积-笛卡尔积
  6. 关于小程序中过滤关键词,敏感词 ,敏感词过滤
  7. ios Xib的几种用法[转]
  8. Android 10.0修改RAM(运行内存)的值
  9. 什么是双因子认证(2FA)
  10. 易语言2020年POST教程