一、栈的定义
栈是限定仅在表尾进行插入或删除操作的线性表。
栈的表尾称为栈顶,表头称为栈底,不含元素的空表称为空栈。
栈的抽象数据类型定义:
ADT Stack{
数据对象:D={ai|ai(- ElemSet,i=1,2,...,n,n>=0}
数据关系:R1={<ai-1,ai>|ai-1,ai(- D,i=2,...,n}
基本操作:
InitStack(&S) 构造一个空栈S
DestroyStack(&S) 栈S存在则栈S被销毁
ClearStack(&S) 栈S存在则清为空栈
StackEmpty(S) 栈S存在则返回TRUE,否则FALSE
StackLength(S) 栈S存在则返回S的元素个数,即栈的长度
GetTop(S,&e) 栈S存在且非空则返回S的栈顶元素
Push(&S,e) 栈S存在则插入元素e为新的栈顶元素
Pop(&S,&e) 栈S存在且非空则删除S的栈顶元素并用e返回其值
StackTraverse(S,visit())栈S存在且非空则从栈底到栈顶依次对S的每个数据元素调用函数visit()一旦visit()失败,则操作失败
}ADT Stack
二、栈的表示和实现
栈的存储方式:
1、顺序栈:利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置
2、链栈:利用链表实现
顺序栈的类C语言定义:
typedef struct{
SElemType *base;
SElemType *top; //设栈顶栈底两指针的目的是便于判断栈是否为空
int StackSize; //栈的当前可使用的最大容量.
}SqStack;
三.栈的链式表示
#include<stdio.h>
#include<malloc.h>
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OK 1
#define EQUAL 1
#define OVERFLOW -1
#define STACKINCREMENT 10
typedef int Status ;
struct STU{
char name[20];
char stuno[10];
int age;
int score;
};
typedef struct STU ElemType;
struct STACK
{
ElemType data;
int stacksize;
struct STACK *next,*base,*top;
};
typedef struct STACK SqStack;
typedef struct STACK *pSqstack;
Status InitStack(SqStack **S); /*¹¹Ôì¿ÕÕ»S*/
Status DestroyStack(SqStack *S); /*Ïú»ÙÕ»S*/
Status ClearStack(SqStack *S); /*°ÑSÖÃΪ¿ÕÕ»*/
Status StackEmpty(SqStack S); /*ÈôջΪ¿ÕÕ»,Ôò·µ»ØTRUE,·ñÔò·µ»ØFALSE*/
int StackLength(SqStack S); /*·µ»ØSµÄÔªËظöÊý*/
Status GetTop(SqStack S,ElemType *e); /*ÈôÕ»²»¿Õ,ÔòÓÃe·µ»ØSµÄÕ»¶¥ÔªËØ,²¢·µ»ØOK;·ñÔò·µ»ØERROR*/
Status Push(SqStack *S,ElemType e); /*²åÈëÔªËØeΪеÄÕ»¶¥ÔªËØ*/
Status Pop(SqStack *S,ElemType *e); /*ÈôÕ»²»¿Õ,Ôòɾ³ýSµÄÕ»¶¥ÔªËØ,ÓÃe·µ»ØÆäÖµ,²¢·µ»ØOK,·ñÔò·µ»ØERRO*/
Status StackTraverse(SqStack S); /*´òÓ¡Õ»²Ù×÷*/
Status InitStack(SqStack **S)
{
(*S)=(pSqstack)malloc(sizeof(SqStack));
if(!(*S)) exit(OVERFLOW);
(*S)->next=NULL;
(*S)->top=(*S)->base=NULL;
return OK;
}
Status DestroyStack(SqStack *S)
{
free(S->base);
free(S);
}
Status ClearStack(SqStack *S)
{
S->top=S->base=NULL;
}
Status StackEmpty(SqStack S)
{
if(S.top==S.base) return TRUE;
else
return FALSE;
}
int StackLength(SqStack S)
{
int i;
SqStack *p;
i=0;
p=S.base;
while(p!=NULL)
{p=p->next;
i++;
}
return i;
}
Status GetTop(SqStack S,ElemType *e)
{
SqStack *p;
if(S.top==S.base) return ERROR;
p=S.base;
while (p->next!=S.top)
{
p=p->next;
}
*e=p->data;
return OK;
}
Status Push(SqStack *S,ElemType 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;
}
*/
pSqstack p;
p=(pSqstack)malloc(sizeof(SqStack));
p->data=e;
if (S->base==NULL)
{
S->base=p;
S->top=S->base;
S->top->next=NULL;
}
else
{
S->top->next=p;
S->top=S->top->next;
S->top->next=NULL;
}
return OK;
}
Status Pop(SqStack *S,ElemType *e)
{
SqStack *p,*q;
if(S->top==NULL) return ERROR;
p=S->top;
*e=(*p).data;
q=S->base;
while (q->next!=S->top)
{
q=q->next;
}
S->top=q;
q->next=NULL;
return OK;
}
Status StackTraverse(SqStack S)
{
SqStack *p;
p=S.base;
while(p!=NULL)
{
printf("%s %s %d %d\n",(p->data).name,(p->data).stuno,(p->data).age,(p->data).score);
p=p->next;
}
}
main()
{
ElemType e;
SqStack *Sa;
/*clrscr();*/
printf("\n\n-------------------SqStack Demo is running...----------------\n\n");
printf("First is Push function.\n");
InitStack(&Sa);
strcpy(e.name,"stu1");
strcpy(e.stuno,"100001");
e.age=80;
e.score=1000;
Push(Sa,e);
printf(" Now Stack has one element.\n");
StackTraverse(*Sa);
getch();
strcpy(e.name,"stu3");
strcpy(e.stuno,"100002");
e.age=80;
e.score=1000;
Push(Sa,e);
printf(" Now Stack has another element.\n\n");
StackTraverse(*Sa);
getch();
printf(" The Stack length is %d:\n\n",StackLength(*Sa));
printf(" Now Pop Stack,the top elem put into variable e.\n\n");
Pop(Sa,&e);
printf("%s\n%s\n%d\n%d\n",e.name,e.stuno,e.age,e.score);
printf(" The Stack length is %d:\n\n",StackLength(*Sa));
printf(" Let's see the left of Stack's elem:\n");
StackTraverse(*Sa);
getch();
printf("\n\n\nWelcom to visit http://zmofun.topcool.net\n\n");
getch();
return 0;
}