以前读谭浩强的C程序设计,里面说Hanoi(汉诺)问题是一个古典的数学问题,是一个只有用递归方法才能解决的问题。我以前一直就怀疑这个。前段时间找了一个不用递归方法的算法。虽然这个方法是从递归方法中得到提示,但里面的确没有用到递归。
递归算法如下:
#include
<
stdio.h
>
void move( char x, char y)
... {
printf("%c -> %c ", x, y);
}
void hanoi( int n, char one, char two, char three)
... {
if(n == 1)
move(one , three);
else
...{
hanoi(n-1, one ,three, two);
move(one, three);
hanoi(n-1, two, one, three);
}
}
int main()
... {
int m;
printf("input the number of diskes:");
scanf("%d", &m);
printf("the step to moving %3d deskes: ", m);
hanoi(m, 'A', 'B', 'C');
return 1;
}
void move( char x, char y)
... {
printf("%c -> %c ", x, y);
}
void hanoi( int n, char one, char two, char three)
... {
if(n == 1)
move(one , three);
else
...{
hanoi(n-1, one ,three, two);
move(one, three);
hanoi(n-1, two, one, three);
}
}
int main()
... {
int m;
printf("input the number of diskes:");
scanf("%d", &m);
printf("the step to moving %3d deskes: ", m);
hanoi(m, 'A', 'B', 'C');
return 1;
}
我的算法:
#include
<
stdio.h
>
#include < stdlib.h >
struct node
... {
char a, b, c;
bool count;
} ;
struct record
... {
char b1,b2;
} ;
void init(node * head, int n, int i, record & temp)
... {
node *p, *q;
p = head;
head->a = 'A';
head->b = 'B';
head->c = 'C';
head->count = 0;
for(q = p+1; n > 0; n--)
...{
if(i&1<<(n-1))
...{
q->a = p->b;
q->b = p->a;
q->c = p->c;
q->count = 1;
temp.b1 = q->b;
temp.b2 = q->c;
p = q; q++;
}
else
...{
q->a = p->a;
q->b = p->c;
q->c = p->b;
q->count = 0;
p = q; q++;
}
}
}
void adjust(node * head, int n, record & temp)
... {
node *p, *q, *end;
for(q = head + n; q->count; q--);
p = q-1;
q->a = p->b;
q->b = p->a;
q->c = p->c;
q->count = 1;
temp.b1 = q->b;
temp.b2 = q->c;
for(p=q, q++, end = head + n; q <= end;)
...{
q->a = p->a;
q->b = p->c;
q->c = p->b;
q->count = 0;
p = q;
q++;
}
}
void output(node * head, int n, int i, int j)
... {
record temp;
init(head, n, i, temp);
printf("%c -> %c ", temp.b1, temp.b2);
for(int k = i + 1; k <=j; k++)
...{
adjust(head, n, temp); //init(head, n, k, temp);
printf("%c -> %c ", temp.b1, temp.b2);
}
}
int main()
... {
int n,i,j;
printf("输入n:");
scanf("%d", &n);
printf("输入需要打印的i到j步骤:");
scanf("%d %d", &i, &j);
if(i<0||i>((1<<n)-1)||j<0||j>((1<<n)-1)||i>j)
...{
printf("输入错误!");
}
node *head = (node *)malloc((n+1)*sizeof(node));
if(i==0&&j==0)
...{
output(head,n,1,(1<<n)-1);
}
else
...{
output(head,n,i,j);
}
free(head);
return 0;
}
#include < stdlib.h >
struct node
... {
char a, b, c;
bool count;
} ;
struct record
... {
char b1,b2;
} ;
void init(node * head, int n, int i, record & temp)
... {
node *p, *q;
p = head;
head->a = 'A';
head->b = 'B';
head->c = 'C';
head->count = 0;
for(q = p+1; n > 0; n--)
...{
if(i&1<<(n-1))
...{
q->a = p->b;
q->b = p->a;
q->c = p->c;
q->count = 1;
temp.b1 = q->b;
temp.b2 = q->c;
p = q; q++;
}
else
...{
q->a = p->a;
q->b = p->c;
q->c = p->b;
q->count = 0;
p = q; q++;
}
}
}
void adjust(node * head, int n, record & temp)
... {
node *p, *q, *end;
for(q = head + n; q->count; q--);
p = q-1;
q->a = p->b;
q->b = p->a;
q->c = p->c;
q->count = 1;
temp.b1 = q->b;
temp.b2 = q->c;
for(p=q, q++, end = head + n; q <= end;)
...{
q->a = p->a;
q->b = p->c;
q->c = p->b;
q->count = 0;
p = q;
q++;
}
}
void output(node * head, int n, int i, int j)
... {
record temp;
init(head, n, i, temp);
printf("%c -> %c ", temp.b1, temp.b2);
for(int k = i + 1; k <=j; k++)
...{
adjust(head, n, temp); //init(head, n, k, temp);
printf("%c -> %c ", temp.b1, temp.b2);
}
}
int main()
... {
int n,i,j;
printf("输入n:");
scanf("%d", &n);
printf("输入需要打印的i到j步骤:");
scanf("%d %d", &i, &j);
if(i<0||i>((1<<n)-1)||j<0||j>((1<<n)-1)||i>j)
...{
printf("输入错误!");
}
node *head = (node *)malloc((n+1)*sizeof(node));
if(i==0&&j==0)
...{
output(head,n,1,(1<<n)-1);
}
else
...{
output(head,n,i,j);
}
free(head);
return 0;
}
这个算法可以打印汉诺问题解法的任意一步或者是全部。经过调试算法和递归的速度差不多。
其实算法还可以修改。