Hanoi Tower

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

你可能感兴趣的:(HA)