栈和队列
栈和队列是一种特殊的线性表。
从数据结构角度看:栈和队列也是线性表,其特点性在于栈和队列的基本操作是线性表操作的子集。它们是操作受限的线性表。
从数据类型角度看:它们是和线性表不相同的两类重要的抽象数据类型。
栈的定义
栈(Stack)是限定仅在表尾进行插入或删除操作的线性表。允许经行插入删除操作的表尾被称为栈顶,相应的表头被称为栈底。
向栈中插入一个元素称为入栈(压栈),从栈中删除一个元素称为出栈(退栈)。栈中无数据元素时称为空栈。
栈的特点:先进后出,后进先出(LIFO)。
栈的表示与实现
和线性表类似,栈也有两种存储表示方法即:顺序和链式。
1,栈的链式存储:因为栈也是线性表,所以线性表的不带头结点单链表结构可以作为栈的链式结构。这样,就可以利用单链表的操作了。
如:
单链表初始化的表头可以作为栈的表头;
单链表 ListInsert(S, 1, e)可以作为栈的入栈操作Push;
单链表ListDeleteS,1, *e)可以作为栈的出栈操作Pop;
单链表的头插法,可以创建一个栈。
2,栈的顺序存储:有关详细信息请看教材46页
//-----栈的顺序存储表示------
typedef struct {
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
栈的基本操作
//------基本操作-----------
Status InitStack(SqStack *S){
//构造一个空栈
(*S).base =(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!(*S).base) exit(OVERFLOW);
(*S).top =(*S).base;
(*S).stacksize =STACK_INIT_SIZE;
return OK;
}
//2
Status DestroyStack(SqStack *S){
//销毁一个栈
free( (*S).base);//释放表
(*S).top =NULL;
(*S).base =NULL;
(*S).stacksize =0;
return OK;
}
//3,
Status ClearStack(SqStack *S){
//设置表为空
(*S).top =(*S).base;//指向栈底
return OK;
}
//4
Status StackEmpty(SqStack S){
//是否为空
if(S.top == S.base)
return TRUE;
else
return FALSE;
}
//5
int StackLength(SqStack S){
//返回栈的长度
return S.top-S.base;
}
//6
Status GetTop(SqStack S,SElemType *e){
//如栈不空,返回栈顶元素
if(S.top == S.base)
return ERROR;
*e =*(S.top-1); //返回栈顶元素
return OK;
}
//7
Status Push(SqStack *S,SElemType e){
//入栈操作
//判断栈满
if( (*S).top-(*S).base >(*S).stacksize){
(*S).base =(SElemType *)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!(*S).base) exit(OVERFLOW);
(*S).top =(*S).base+(*S).stacksize;//重新定位栈顶指针
(*S).stacksize+=STACKINCREMENT;
}
*( (*S).top )++ =e; //先插入,栈顶指针在+1
return OK;
}
//8
Status Pop(SqStack *S,SElemType *e){
//出栈操作
//判断是否为空
if((*S).top ==(*S).base) return ERROR;
*e= *--(*S).top;//先栈顶指针-1,在取元素
return OK;
}
//9
Status StackTraverse(SqStack S,Status(*visit)(SElemType))
{ // 从栈底到栈顶依次对栈中每个元素调用函数visit()
while(S.top>S.base)
visit(*S.base++);
printf("\n");
return OK;
}
测试代码:
#include"ch2.h"
typedef int SElemType;
#include"Stack.c"
Status visit(SElemType c)
{
printf("%d ",c);
return OK;
}
//-----测试----
main(){
int j;
SqStack s;
SElemType e;
//
printf("--------测试------------\n");
printf("---初始化栈,并把1-6入栈---\n");
if(InitStack(&s)==OK)
for(j=1;j<=6;j++)
Push(&s,j);
printf("栈中元素依次为:");
StackTraverse(s,visit);
printf("---出栈操作---\n");
Pop(&s,&e);
printf("弹出的栈顶元素 e=%d\n",e);
printf("栈是否空:%d(1:空 0:否)\n",StackEmpty(s));
printf("---获取栈顶元素及栈的长度---\n");
GetTop(s,&e);
printf("栈顶元素 e=%d 栈的长度为%d\n",e,StackLength(s));
printf("---清空栈---\n");
ClearStack(&s);
printf("清空栈后,栈是否空:%d(1:空 0:否)\n",StackEmpty(s));
printf("---销毁栈---\n");
DestroyStack(&s);
printf("销毁栈后,s.top=%u s.base=%u s.stacksize=%d\n",s.top,s.base, s.stacksize);
}
测试结果图: