编写代码是为了使用堆栈操作解决汉诺塔问题,但输出会无限期地打印出来。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_SIZE 100
struct stack{
int a[MAX_SIZE];
int top;
}x, y, z;
typedef struct stack stk;
void push(stk *s, char n)
{
if(s->top == MAX_SIZE-1)
printf("Stack Overflow\n");
else
s->a[++s->top] = n;
}
int pop(stk *s)
{
if(s->top < 0)
{
printf("Stack Underflow\n");
return -1;
}
else
{
return s->a[s->top--];
}
}
int top(stk *s)
{
if(s->top < 0)
{
return -1;
}
else
{
return s->a[s->top];
}
}
int isEmptyStack(stk *s)
{
if(s->top < 0)
{
return 1;
}
else
{
return 0;
}
}
int isFullStack(stk *s)
{
if(s->top == MAX_SIZE - 1)
{
return 1;
}
else
{
return 0;
}
}
int size(stk *s)
{
return s->top;
}
int main()
{
x.top = -1;
y.top = -1;
z.top = -1;
int n;
printf("Enter number of disks: ");
scanf("%d", &n);
for(int i=0;i<n;i++)
{
push(&x, i+1);
}
if(n > 0)
{
while(size(&z) < n-1)
{
if(n % 2 != 0)
{
if(top(&x) > top(&z))
{
push(&z, pop(&x));
printf("X to Z\n");
}
if(top(&z) > top(&x))
{
push(&x, pop(&z));
printf("Z to X\n");
}
if(top(&x) > top(&y))
{
push(&y, pop(&x));
printf("X to Y\n");
}
if(top(&y) > top(&x))
{
push(&x, pop(&y));
printf("Z to X\n");
}
if(top(&y) > top(&z))
{
push(&z, pop(&y));
printf("Y to Z\n");
}
if(top(&z) > top(&y))
{
push(&y, pop(&z));
printf("Z to Y\n");
}
}
else
{
if(top(&x) > top(&y))
{
push(&y, pop(&x));
printf("X to Y\n");
}
if(top(&y) > top(&x))
{
push(&x, pop(&y));
printf("Y to X\n");
}
if(top(&x) > top(&z))
{
push(&z, pop(&x));
printf("X to Z\n");
}
if(top(&z) > top(&x))
{
push(&x, pop(&z));
printf("Z to X\n");
}
if(top(&y) > top(&z))
{
push(&z, pop(&y));
printf("Y to Z\n");
}
if(top(&z) > top(&y))
{
push(&y, pop(&z));
printf("Z to Y\n");
}
}
}
}
return 0;
}
我期待条件
size(&z) < n-1
变成 0
这将终止循环,但循环没有终止。
航站楼:
Enter number of disks: 3
*Out of control output*
有人建议我使用调试器,但我不知道如何使用它,因为我只是在学习使用它。
无限循环意味着循环条件(在本例中为
size(&z) < n-1
)永远保持为真。由于右侧 (rhs) n-1
固定为 n = 3
这意味着您期望 size(&z)
至少增加到 2 但它永远不会增加。从输出中我们看到一个重复的循环:
Z to X
X to Y
Z to X
X to Z
Z to X
...
这告诉我们,我们将一个值推到
z
并立即将其弹出,因此我们永远不会取得进展。
我建议你修改你的界面,这样你的错误域(-1)和值域就不会重叠。如果你
push(..., -1)
现在你不知道什么时候 top(...)
返回 -1 如果它是一个错误或者它恰好是你推送的最后一个值。 pop()
有同样的问题,而且,来电者也不知道,但至少有一条错误消息。
在您的情况下,要么禁止推送 -1,要么让函数返回操作状态并通过您传入的指针返回值(此处使用常量 OK 以提高可读性):
#define OK 0
int push(stk *s, char n) {
if(s->top == MAX_SIZE-1) {
printf("Stack Overflow\n");
return !OK;
}
s->a[++s->top] = n;
return OK;
}
int pop(stk *s, int *v) {
if(s->top < 0) {
printf("Stack Underflow\n");
return !OK;
}
*v = s->a[s->top--];
return OK;
}