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单链表中保存的移动操作步骤可以用于图形化显示(待续。。。)

posted @ 2010-03-23 09:57  wlu  阅读(287)  评论(0编辑  收藏  举报