我尽了最大的努力,但我不知道错误在哪里?我来解释一下这个程序。在这个程序中,我应该实现一个整数链表堆栈,使用全局变量将指向堆栈的顶部,方法如下:
int push(int i);
将I压入堆栈,如果成功则返回1,否则返回0。
int pop();
从堆栈中弹出数字。如果堆栈为空,返回0;
我确实创建了新的方法调用int stackEmpty();
和上面的两个方法。
每次我运行我的程序,它都把数字压入堆栈,但是弹出不起作用。下面是我的代码:::
#include <stdio.h>
#include <stdlib.h>
typedef struct stack Stack;
struct stack
{
int number;
Stack *next;
};
Stack *top = NULL;
int push(int i);
int count();
int stackEmpty();
int pop();
int main()
{
char op;
int i, x;
printf("Welcome to my stackn");
printf("p to pop, s to push, c to count, q to quitn");
while (op != 'q')
{
scanf("%c", &op);
if (op == 'p')
{
x = pop();
if (x == 0)
{
printf("Stack is emptyn");
}
else
{
printf("%d poppedn", pop());
}
}
else if (op == 'c')
{
i = count();
printf("%d numbers on stackn", i);
}
else if (op == 's')
{
printf("Enter number: ");
scanf("%d", &i);
x = push(i);
if (x == 1 || x == 2)
{
printf("%d puched :: state%dn", i, x);
}
else
{
printf("faill %dn", x);
}
}
else if (op == 'q')
{
return 0;
}
}
return 0;
}
int stackEmpty()
{
if (top == NULL)
{
return 1;
}
else
{
return 0;
}
}
int count()
{
int counter = 0;
if (top == NULL)
{
return counter;
}
else
{
while (top != NULL)
{
top = top->next;
counter++;
}
return counter;
}
}
int push(int i)
{
Stack *head;
Stack *next;
Stack *new;
int state;
int m;
head = top;
new = (Stack *) malloc(sizeof(Stack));
if (new == NULL)
{
state = 0;
} new->number = i;
m = stackEmpty();
if (m == 1)
{
head = new;
top = head;
head->next = NULL;
state = 1;
}
else
{
while (head != NULL)
{
if ((next = head->next) == NULL)
next = new;
next->next = NULL;
state = 2;
break;
head = top->next;
next = head->next;
}
top = head;
}
return state;
}
int pop()
{
Stack *head;
int state;
int m;
head = top;
if (head == NULL)
{
state = 0;
}
m = stackEmpty();
if (m == 1)
{
state = 0;
}
else
{
state = head->number;
top = head->next;
free(head);
}
return state;
}
几个问题:
-
top
是你假定的堆栈头。在count
中,你前进到顶部,直到NULL
-因此,一旦你调用count
,你已经"丢失"了你的堆栈。栈是后进先出队列(后进先出)。你的推送将通过在末尾附加新元素来实现FIFO(先进先出)。 - 你的推送实际上并没有添加任何东西到列表中。您只是将
new
分配给next
,但您没有从列表中的任何地方指向下一个。 - 当使用
pop
时,你调用它两次(一次用于删除元素,一次用于打印)。因此,无论何时沿着该代码路径运行,都要删除两个元素。一个更好的实现是编写一个peek
函数,它返回顶部元素而不删除它,pop
函数只是删除它(用1表示成功,用0表示失败)
栈的push是这样的:
- 新建元素
- 指向你当前的头部作为下一个元素
- 让你的新元素成为栈头
不需要循环。这是一个0(1)的操作
你推错了。您正在更改next,这是一个局部变量。
一个问题是,你pop()
,然后检查结果,然后pop()
再次打印。每次尝试打印时都会弹出两次。
另一个错误:
while (head != NULL)
{
if ((next = head->next) == NULL)
next = new;
next->next = NULL;
state = 2;
break;
head = top->next;
next = head->next;
}
应: while (head != NULL)
{
if ((next = head->next) == NULL)
{
next = new;
next->next = NULL;
state = 2;
break;
}
head = top->next;
next = head->next;
}
至少,这是你原来的缩进似乎表明。