zoukankan      html  css  js  c++  java
  • Hanoi Tower

    Hanoi tower运用递归算法。几年前没能了解其中的真正奥妙,

    想通了其实很简单,呵呵

    参见了《数据结构及算法分析 JAVA版》

    思路:

    1 设计disk和pole类,其中pole类类似于栈(先入后出)

    2 利用递归算法得出移动disk的先后顺序以及移动路线,并将每一步操作信息保存至链表中

    3 将链表中保存的结果打印出来

    以下是汉诺塔中定义的类:

    HanoiType.h

    代码
    #include <stdio.h>

    // disk type
    class disk
    {
    public:
        
    int id;
        disk 
    *next; // upper one
        disk *pre;  // downer one
        disk(int _id);
    protected:
    private:
    };

    disk::disk(
    int _id)
    {
        id 
    = _id;
        next 
    = NULL;
        pre 
    = NULL;
    }

    // pole with ordered stack data structure
    class pole
    {
    public:
        
    void push(disk *_dsk);
        disk
    * pop();
        disk 
    *head;    // the disk on the tower top
        pole(int _pol_id);
        
    ~pole();
        
    int pole_id;
    protected:
    private:
    };

    void pole::push(disk *_dsk)
    {
        
    if (NULL == _dsk)
        {
            
    return;
        }
        
    if (NULL == head) // the pole is empty
        {
            head 
    = _dsk;
        }
        
    else// the pole is not empty
        {
            _dsk
    ->pre = head;
            head
    ->next = _dsk;
            head 
    = _dsk;
        }
    }

    disk
    * pole::pop()
    {
        
    if (NULL == head)    // the pole is empty
        {
            
    return NULL;
        }
        
    else    // the pole is not empty
        {
            disk 
    *tmp = head;
            head 
    = head->pre;
            
    if (!head)
            {
                
    //head->next = NULL;
            }
            tmp
    ->pre = NULL;
            tmp
    ->next = NULL;
            
    return tmp;
        }
    }

    pole::
    ~pole()
    {
        disk 
    *ptr = head;
        disk 
    *tmp;
        
    while(!ptr)
        {
            tmp 
    = ptr->pre;
            delete ptr;
            ptr 
    = NULL;
            ptr 
    = tmp;
        }
    }

    pole::pole(
    int _pole_id)
    {
        pole_id 
    = _pole_id;
        head 
    = NULL;
    }


    class report_node
    {
    public:
        
    int disk_id;
        
    int src_pole_id;
        
    int des_pole_id;
        report_node 
    *next;
        report_node(
    int _d_id, int _src_p_id, int _des_p_id);
    protected:
    private:
    };

    report_node::report_node(
    int _d_id, int _src_p_id, int _des_p_id)
    {
        disk_id 
    = _d_id;
        src_pole_id 
    = _src_p_id;
        des_pole_id 
    = _des_p_id;
        next 
    = NULL;
    }

    class report
    {
    public:
        report_node 
    *first, *ptr;
        
    void insert(report_node *node);
        report();
        
    ~report();
    protected:
    private:
    };

    report::report()
    {
        first 
    = NULL;
        ptr 
    = NULL;
    }

    report::
    ~report()
    {
        report_node 
    *_ptr = first;
        
    while(!_ptr)
        {
            delete _ptr;
            _ptr 
    = NULL;
        }
    }

    void report::insert(report_node *node)
    {
        
    if (NULL == node)
        {
            
    return;
        }
        
    else if(NULL == first)
        {
            first 
    = node;
            ptr 
    = node;
        }
        
    else
        {
            ptr
    ->next = node;
            ptr 
    = ptr->next;
        }
    }

    以下是源文件

    Movedisks.cpp

    代码
    #include "HanoiType.h"
    #include 
    <iostream>
    using namespace std;

    report 
    *rept = new report();    // store the moving steps

    /* move just one dist from src_pole to des_pol,
     * pop a disk from src and push it into 
     * des;
     
    */
    void move_1(pole *src_pole, pole *des_pole)
    {    
        
    if (NULL == src_pole->head)
        {
            
    return;
        }
        
    else
        {
    //         cout << "move disk --" << src_pole->head->id << "-- on --"
    //             << src_pole->pole_id << "-- to " << "pole " << des_pole->pole_id << endl;
            report_node *step = new report_node(src_pole->head->id, src_pole->pole_id, des_pole->pole_id);
            rept
    ->insert(step);
            disk 
    *src_top = src_pole->pop();
            des_pole
    ->push(src_top);
        }
    }

    void move_disks(int n, pole *src_pole, pole *emp_pole, pole *des_pole)
    {    
        
    if (0 == n)
        {
            
    return;
        }
        
    else if (1 == n)    // basic condition
        {
            move_1(src_pole, des_pole);
        }
        
    else
        {
            move_disks(n 
    - 1, src_pole, des_pole, emp_pole);
            move_1(src_pole, des_pole);
            move_disks(n 
    - 1, emp_pole, src_pole, des_pole);
        }
    }


    void main()
    {
        
    int N = 3// number of disks on src pole
        pole *src_pole = new pole(0);
        pole 
    *emp_pole = new pole(1);
        pole 
    *des_pole = new pole(2);
        
    // construct the s
        for(int i = N; i != 0; i--)
        {
            disk 
    *= new disk(i);
            src_pole
    ->push(d);
        }
        
    // begin
        move_disks(N, src_pole, emp_pole, des_pole);
        report_node 
    *_ptr = rept->first;
        
    while(_ptr)
        { 
            cout 
    << "Move disk --" << _ptr->disk_id << " -- from pole "<<_ptr->src_pole_id << " to " << _ptr->des_pole_id << endl;
            _ptr 
    = _ptr->next;
        }

    }

     在report单链表中保存的移动操作步骤可以用于图形化显示(待续。。。)

  • 相关阅读:
    修改编译8266NodeMCU固件 打开各种模块以及修改支持智能配网
    3实现8266智能配网并打印出ip地址 8266 lua nodemcu 智能配网 一键配网
    8266 开发环境教程 nodemcu lua开发8266教程 输出世界你好
    代码提交量查询
    antd DatePicker框日期限制
    form表单设置值
    a标签传参数
    css获取页面高度,定位部分信息
    Form自定义校验
    下拉框可输入或输入为下拉框对应的值
  • 原文地址:https://www.cnblogs.com/luweiseu/p/1692258.html
Copyright © 2011-2022 走看看