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;
}
#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




















































































































































*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 = (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;
}
#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 = (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;
}