概念
撤回,即 Ctrl+Z,是我们最常见的操作之一,大多数应用都会支持这个功能。你知道它是怎么实现的吗?答案是这样的:把之前的应用状态(限制个数)保存到内存中,最近的状态放到第一个。这时,我们需要栈(stack)来实现这个功能。
栈中的元素采用 LIFO (Last In First Out),即后进先出。
下图的栈有 3 个元素,3 在最上面,因此它会被第一个移除:
栈的基本操作
- Push — 在栈的最上方插入元素
- Pop — 返回栈最上方的元素,并将其删除
- isEmpty — 查询栈是否为空
- Top — 返回栈最上方的元素,并不删除
C语言实现
栈的变量定义
#define STACK_SIZE 10
#define OK 1
#define ERROR -1
#define EMPTY 1
#define NOEMPTY !EMPTY
#define STACKINCREMENT 10
typedef int ElemType;
typedef int Status;
栈的结构体
typedef strucT SqStack
{
int top;
int bottom;
ElemType array[STACK_SIZE];
}SqStack;
栈的初始化
Status Init_Stack(SqStack *S)
{
S->top = S->bottom = 0;
return OK;
}
入栈:
Status Push(SqStack *S,ElemType e)
{
if(S->top >= STACK_SIZE)
{
printf("The stack is full\n");
return ERROR;
}
S->array[(S->top)++] = e;
return OK;
}
出栈:
Status Pop(SqStack *S,ElemType *e)
{
if(S->top == S->bottom)
{
printf("The stack is empty\n");
return ERROR;
}
(S->top)--;
*e = S->array[S->top];
return OK;
}
获取栈顶元素
Status GetTop(SqStack *S,ElemType *e)
{
if(S->top == S->bottom)
{
printf("The stack is empty\n");
return ERROR;
}
*e = S->array[S->top-1];
return OK;
}
判断是否为空
Status isEmpty(SqStack *S)
{
if(S->top == S->bottom)
{
printf("The stack is empty\n");
return EMPTY;
}
return NOEMPTY;
}
返回栈的长度
Status StackLength(SqStack *S)
{
if(S->top == S->bottom)
{
printf("The stack is empty\n");
return ERROR;
}
return (S->top-S->bottom);
}
清理栈
Status ClearStack(SqStack *S)
{
S->top = S->bottom;
return OK;
}
输出所有栈元素:
Status OutPut_Stack(SqStack *S)
{
int i=0;
int j=0;
int len = S->top-S->bottom;
if(S->top == S->bottom)
{
printf("The stack is empty\n");
return ERROR;
}
j = len;
for(i=len-1;i>=0;i--)
{
printf("第%d个元素为:%d\r\n",j,S->array[i]);
j--;
}
return OK;
}
测试函数:
int main(int argc, char* argv[])
{
int i;
int a;
int j = 0;
SqStack S;
int res1 = 0;//初始化栈的返回值
int res2 = 0;//压入栈的返回值
int res3 = 0;//获取栈顶元素的返回值
int res4 = -1;//弹出栈顶元素的返回值
int res6 = 0;//清除栈的返回值
ElemType e1,e2;
printf("1.初始化一个栈\n2.压入一个元素\n3.弹出栈顶元素\n4.获取栈的长度\n5.输出站\n6.获取栈顶元素\n7.清空栈\n");
while(1)
{
printf("请输入操作编号:");
scanf("%d", &i);
printf("\n");
if(i == 1)
{
//初始化一个栈
res1 = Init_Stack(&S);
if(res1 == 1)
printf("初始化成功\n\n");
else
printf("初始化失败\n\n");
res2 = 0;
j = 1;
}
else if(i == 2)
{
//压入元素
if(j == 0)
{
printf("Error!\n");
printf("Please initialize a stack first!\n");
}
else
{
printf("请插入数据:");
scanf("%d", &a);
printf("\n");
res2 = Push(&S, a);
if(res2 == 1)
printf("元素压入成功\n\n");
else
printf("元素压入失败\n\n");
res2 = 0;
}
}
else if(i == 3)
{
if(j == 0)
{
printf("Error!\n");
printf("Please initialize a stack first!\n");
}
else
{
printf("\n-----------弹出栈顶元素-----------\n\n");
res4 = Pop(&S,&e1);
if(res4 != -1)
{
printf("栈顶元素弹出成功\n");
printf("栈顶元素为:%d\n", e1);
}
}
}
else if(i == 4)
{
if(j == 0)
{
printf("Error!\n");
printf("Please initialize a stack first!\n");
}
else
{
printf("栈的长度:%d\n",StackLength(&S));
}
}
else if(i == 5)
{
if(j == 0)
{
printf("Error!\n");
printf("Please initialize a stack first!\n");
}
else
{
printf("\n-----------输出栈-----------\n\n");
OutPut_Stack(&S);
}
}
else if(i == 6)
{
if(j == 0)
{
printf("Error!\n");
printf("Please initialize a stack first!\n");
}
else
{
printf("\n-----------获取栈顶元素-----------\n\n");
res3 = GetTop(&S,&e2);
printf("栈顶元素为:%d\n", e2);
}
}
else if(i == 7)
{
if(j == 0)
{
printf("Error!\n");
printf("Please initialize a stack first!\n");
}
else
{
printf("\n-----------清空栈-----------\n\n");
//清空栈
res6 = ClearStack(&S);
if(res6 == OK)
printf("清除成功\n");
else
printf("清除失败\n");
}
}
else
{
printf("操作编码错误\n请重新输入\n");
}
}
return 0;
}