A Brief Summary of Towers of Hanoi Puzzle

本文介绍了汉诺塔问题的三种解决方法:递归方法、使用栈模拟递归过程的方法及纯非递归方法,并提供了详细的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Just spent some time code all the three solutions. So far I haven't added complexity analysis and will append it later: 
 
*recursive approach:

#include <cstdio>
#include 
<iostream>


using namespace std;


void movedisk(int n, char src,  char desc, int* tsrc, int* tdesc);
void movetower(int n, char src, char aid, char desc, int* tsrc, int* taid, int* tdesc);
void printtowers(int n, const char* towers, int* tsrc, int* taid, int* tdesc);


int* tsrc = NULL; 
int* taid = NULL;
int* tdesc = NULL;
int g_height = 1;
char* towers = "ABC";

void main()
{
    
int n = 1;
    
    
    cout
<<"please input the tower height:" << endl;
    cin 
>> n;

    
if(n <1
    {
        cout 
<< "invalid tower height(must be greater than 0)!" << endl;
        
return;
    }

    g_height 
= n;
    tsrc 
= new int[n];
    taid 
= new int[n];
    tdesc 
= new int[n];

    
for(int i= 0;i<n;++i)
    {
        tsrc[i] 
=i+1;
        taid[i] 
= 0;
        tdesc[i] 
= 0;
    }

    
//printtowers(g_height, towers, tsrc, taid, tdesc);

    movetower(n, towers[
0], towers[1], towers[2], tsrc, taid, tdesc);

    
//printtowers(g_height, towers, tsrc, taid, tdesc);


    delete(tsrc);
    delete(taid);
    delete(tdesc);

}

void movedisk(int n, char src, char desc, int* tsrc, int* tdesc)
{
    cout
<<    "move disk("    <<    n    <<    "): "    << src << " ---> " << desc << endl;
    tsrc[n
-1=0;
    tdesc[n
-1= n;

    
}


void movetower(int n, char src, char aid, char desc, int* tsrc, int* taid, int* tdesc)
{
    
if(n<1
    {
        cout
<<"invalid tower height!";
        
return;
    }

    
if( n == 1)
    {
        movedisk(n, src, desc, tsrc, tdesc);
    }
else
    {
        movetower(n
-1, src, desc, aid, tsrc, tdesc, taid);
        movedisk(n, src, desc, tsrc, tdesc);
        movetower(n
-1,aid, src, desc, taid, tsrc, tdesc);
    }

    
//printtowers(g_height, towers, tsrc, taid, tdesc);

    
}

void printtowers(int n, const char* towers, int* tsrc, int* taid, int* tdesc)
{
    cout
<<endl<<"------current tower status---------"<<endl;
    cout
<<towers[0]<<" "<<towers[1]<<" "<<towers[2]<<endl;

    
for(int i=0;i<n;++i)
    {
        tsrc[i] 
==0 ?cout<<"|": cout<< tsrc[i]; cout << " ";
        taid[i] 
==0 ?cout<<"|": cout<< taid[i]; cout << " ";
        tdesc[i] 
==0 ?cout<<"|": cout<< tdesc[i];
        cout
<<endl;
    }
    cout
<<endl;

}

 

 *use stack to simulate recursive

#include <cstdio>
#include 
<iostream>
#include 
<stack>

using namespace std;

const char* towers = "ABC";



//non-recursive-manual_stack
struct HanoiFrame{

int n;
char x,y,z;
int retln;;


}
;


void hanoi_manual_stack();
void move(int n, char src, char desc);

void main()
{    

hanoi_manual_stack();


}








//hanoi manual stack
void move_manual_stack(int n, char src, char desc)
{
    cout
<<    "move disk("    <<    n    <<    "): "    << src << " ---> " << desc << endl;
}


void hanoi_manual_stack()
{
    
int n = 1;

    cout
<<"please input the tower height:" << endl;
    cin 
>> n;

    
if(n <1
    
{
        cout 
<< "invalid tower height(must be greater than 0)!" << endl;
        
return;
    }



    stack
<HanoiFrame*> hstack;
    HanoiFrame
* pframe = NULL;
    HanoiFrame
* pcurFrame = NULL;

    pframe 
= new HanoiFrame();
    pframe
->= n;
    pframe
->retln=0;
    pframe
->= towers[0];
    pframe
->= towers[1];
    pframe
->= towers[2];

    hstack.push(pframe);
    

    
while(!hstack.empty())
    
{
        pcurFrame 
= hstack.top(); 

        
if(pcurFrame->== 1)
        
{
            move_manual_stack(
1, pcurFrame->x, pcurFrame->z);
            hstack.pop();
            delete(pcurFrame);
        }
else
        
{
            
switch(pcurFrame->retln)
            
{
            
case 0:

                pcurFrame
->retln = 1//hstack.push(*pcurFrame);

                pframe 
= new HanoiFrame();

                pframe
->= pcurFrame->n-1;
                pframe
->retln = 0;
                pframe
->= pcurFrame->x;
                pframe
->= pcurFrame->z;
                pframe
->= pcurFrame->y;

                hstack.push(pframe);

                
break;
            
case 1:

                move_manual_stack(pcurFrame
->n, pcurFrame->x, pcurFrame->z);
                pcurFrame
->retln = 2//hstack.push(*pcurFrame);

                pframe 
= new HanoiFrame();

                pframe
->= pcurFrame->n-1;
                pframe
->retln = 0;
                pframe
->= pcurFrame->y;
                pframe
->= pcurFrame->x;
                pframe
->= pcurFrame->z;

                hstack.push(pframe);

                
break;
            
case 2:

                
//do nothing
                hstack.pop();
                delete(pcurFrame);

                
break;
            
default:

                cout
<<"invalid Frame-->retln";
                exit(
0);
            }



        }


    }


    cout
<<"end........"<<endl;

}


 

*pure non-recursive approach:

#include <cstdio>
#include 
<iostream>
#include 
<stack>


using namespace std;

const char* towers = "ABC";



//non-recursive-non-stack
void hanoi_non_stack();
void do_step(int step, int N);
void move_disk(int n, char src, char desc);

int main()
{    






hanoi_non_stack();






return 0;
}



//non-recursive-non-stack
void hanoi_non_stack()
{
int i=0;
int step = 1;
int n = 1;

cout
<<"please input the tower height:" << endl;
cin 
>> n;

if(n <1
{
    cout 
<< "invalid tower height(must be greater than 0)!" << endl;
    
return;
}


/*
calculate the total steps(steps = 2^n - 1)
*/

for(i=0;i<n;++i) step*=2;

--step;

for(i=1;i<=step;++i)
{
    do_step(i, n);
}


}


/*
对第m=((p*2^k) + 2^(k-1)),易知移动的盘子是第k号,而且这是序列中第p+1个k号盘子,也就是说此前k号盘子已经移动了p次,
那么k号盘现在就在(1+p*(-1)^(N+k+1))%3号柱子上,他将被移动到(1+(p+1)*(-1)^(N+K+1))%3号柱子上。
于是,我们就可以随机得到第m步的情况: 
k号盘从第(1+p*(-1)^(N+k+1))%3号柱子移动到第(1+(p+1)* (-1)^(N+k+1))%3号柱子上。
*/


void do_step(int step, int N)
{
int n = 1;
int p = 0;
int temp = 0;
int isrc,idesc;

p
=step;

while(!(p % 2))
{
    p
/=2;
    
++n;
}

= (p-1)/2;


temp 
= ((1+n+N)%2 == 0)? 1:-1;

isrc 
= (1 + p * temp) %3;
idesc 
=(1 + (p+1* temp) %3;

if(isrc<=0) isrc += 3;
if(idesc<=0) idesc += 3;

move_disk(n, towers[isrc
-1], towers[idesc-1]);
}


void move_disk(int n, char src, char desc)
{
    cout
<<    "move disk("    <<    n    <<    "): "    << src << " ---> " << desc << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值