我正在处理一个非常常见的问题,即用两个堆栈实现队列并用 C 语言完成,因为这给了我一个借口来复习结构和指针的知识。
我分别借助 struct 创建了两个堆栈变量 st1 和 st2 。我将元素推送到 st1 进行入队操作,对于出队,从 st1 弹出元素并同时推送到 st2 。弹出 st2 后,元素再次转移回 st1 (我知道这是多余的,但这不是我面临的问题)。所有这些都已在 中的 switch case 中使用相应的函数实现main()
。
该错误是,当调用出队操作时,st1 的第一个元素会被其他值神秘地覆盖。
完整代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct stack
{
char name[5] ;
int top ;
int *a ;
}Stack ;
int n ;
int main()
{
void push(Stack*,int) ;
int delete(Stack*,Stack*) ;
void display(Stack*) ;
printf("Enter the size of the queue: ") ;
scanf("%d",&n) ;
Stack st1,st2 ;
st1.a = (int*)malloc(n*sizeof(int)) ;
st1.top = -1 ;
st2 = st1 ;
strcpy(st1.name,"st1") ;
strcpy(st2.name,"st2") ;
while(1)
{
printf("Enter 1. to insert.\nEnter 2. to delete.\nEnter 3. to display.\nEnter anything else to exit.\n") ;
char c ;
int e ;
scanf(" %c",&c) ;
switch(c)
{
case '1':
printf("Enter the no. to be inserted: ") ;
scanf("%d",&e) ;
push(&st1,e) ;
break ;
case '2' :
e = delete(&st1,&st2) ;
printf("%d got deleted.\n",e) ;
break ;
case '3' :
display(&st1) ;
break ;
default :
free(st1.a) ;
free(st2.a) ;
return 0 ;
}
}
}
int delete(Stack *st1,Stack *st2)
{
void push(Stack*,int) ;
int pop(Stack*) ;
while(st1->top!=-1)
push(st2,pop(st1)) ;
int e = pop(st2) ;
while(st2->top!=-1)
push(st1,pop(st2)) ;
return e ;
}
void push(Stack *st,int e)
{
void display(Stack*) ;
printf("Operations on %s begin: \n",st->name) ;
printf("Currently %s:\n",st->name) ;
display(st) ;
st->top++ ;
if(st->top==n)
{
printf("Queue full.\n") ;
st->top-- ;
return ;
}
st->a[st->top] = e ;
printf("After operations , %s:\n",st->name) ;
display(st) ;
printf("Operations on %s end.\n\n",st->name) ;
}
int pop(Stack *st)
{
void display(Stack*) ;
printf("Operations on %s begin: \n",st->name) ;
display(st) ;
if(st->top==-1)
{
printf("Queue is empty.\n") ;
return -1 ;
}
int e = st->a[st->top] ;
st->top-- ;
printf("After operations , %s:\n",st->name) ;
display(st) ;
printf("Operations on %s end.\n\n",st->name) ;
return e ;
}
void display(Stack *st)
{
if(st->top==-1)
{
printf("Queue is empty.\n") ;
return ;
}
int i ;
for(i=0;i<=st->top;i++)
printf("%d ",st->a[i]) ;
printf("\n") ;
}
如您所见,我已经编写了printf()
用于调试的语句。以下是输出,您可以看到错误:
Enter the size of the queue: 5
Enter 1. to insert.
Enter 2. to delete.
Enter 3. to display.
Enter anything else to exit.
1
Enter the no. to be inserted: 1
Operations on st1 begin:
Currently st1:
Queue is empty.
After operations , st1:
1
Operations on st1 end.
Enter 1. to insert.
Enter 2. to delete.
Enter 3. to display.
Enter anything else to exit.
1
Enter the no. to be inserted: 2
Operations on st1 begin:
Currently st1:
1
After operations , st1:
1 2
Operations on st1 end.
Enter 1. to insert.
Enter 2. to delete.
Enter 3. to display.
Enter anything else to exit.
2
Operations on st1 begin:
1 2
After operations , st1:
1
Operations on st1 end.
Operations on st2 begin:
Currently st2:
Queue is empty.
After operations , st2:
2
Operations on st2 end.
Operations on st1 begin:
2
After operations , st1:
Queue is empty.
Operations on st1 end.
Operations on st2 begin:
Currently st2:
2
After operations , st2:
2 2
Operations on st2 end.
Operations on st2 begin:
2 2
After operations , st2:
2
Operations on st2 end.
Operations on st2 begin:
2
After operations , st2:
Queue is empty.
Operations on st2 end.
Operations on st1 begin:
Currently st1:
Queue is empty.
After operations , st1:
2
Operations on st1 end.
2 got deleted.
Enter 1. to insert.
Enter 2. to delete.
Enter 3. to display.
Enter anything else to exit.
您可以看到,当我调用出队操作时,从 st1 弹出 2 并将其推入 st2 之后,0
st1 的第 th 索引从 更改1
为2
。
这个问题困扰了我好久。我以为是指针出了问题,所以我把所有指针都删除了,然后做了同样的事情,但通过值传递了堆栈变量。当我这样做时,出现了一个更大的问题,每次我插入一个值时,它都会以某种方式自动被删除。所以当我下次尝试插入时,之前的插入已经消失了。
我觉得存在一些导致这些问题的根本问题,需要解决这些问题才能使代码正常运行。
st1
和st2
使用相同的内存a
,因为st2 = st1
只是复制a
指针,而不会复制它指向的内存。所以你需要分别分配它们。此外,在 C 语言中你不应该转换的结果
malloc()
。