栈的表示和实现

来源:互联网 发布:135端口还有漏洞吗 编辑:程序博客网 时间:2024/05/16 17:21
// c3-1.h 栈的顺序存储结构(见图3.1)#define STACK_INIT_SIZE 10 // 存储空间初始分配量#define STACK_INCREMENT 2 // 存储空间分配增量struct SqStack{SElemType *base; // 在栈构造之前和销毁之后,base的值为NULLSElemType *top; // 栈顶指针int stacksize; // 当前已分配的存储空间,以元素为单位}; // 顺序栈

// bo3-1.cpp 顺序栈(存储结构由c3-1.h定义)的基本操作(9个)void InitStack(SqStack &S){ // 构造一个空栈S(见图3.2)if(!(S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType))))exit(OVERFLOW); // 存储分配失败S.top=S.base;S.stacksize=STACK_INIT_SIZE;}void DestroyStack(SqStack &S){ // 销毁栈S,S不再存在(见图3.3)free(S.base);S.base=NULL;S.top=NULL;S.stacksize=0;}void ClearStack(SqStack &S){ // 把S置为空栈S.top=S.base;}Status StackEmpty(SqStack S){ // 若栈S为空栈,则返回TRUE;否则返回FALSEif(S.top==S.base)return TRUE;elsereturn FALSE;}int StackLength(SqStack S){ // 返回S的元素个数,即栈的长度return S.top-S.base;}Status GetTop(SqStack S,SElemType &e){ // 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERRORif(S.top>S.base){e=*(S.top-1);return OK;}elsereturn ERROR;}void Push(SqStack &S,SElemType e){ // 插入元素e为新的栈顶元素(见图3.4)if(S.top-S.base>=S.stacksize) // 栈满,追加存储空间{S.base=(SElemType *)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(SElemType));if(!S.base)exit(OVERFLOW); // 存储分配失败S.top=S.base+S.stacksize;S.stacksize+=STACK_INCREMENT;}*(S.top)++=e;}Status Pop(SqStack &S,SElemType &e){ // 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;// 否则返回ERROR(见图3.5)if(S.top==S.base)return ERROR;e=*--S.top;return OK;}void StackTraverse(SqStack S,void(*visit)(SElemType)){ // 从栈底到栈顶依次对栈中每个元素调用函数visit()while(S.top>S.base)visit(*S.base++);printf("\n");}

// main3-1.cpp 检验bo3-1.cpp的主程序#include"c1.h"typedef int SElemType; // 定义栈元素类型,此句要在c3-1.h的前面#include"c3-1.h"#include"bo3-1.cpp"void print(SElemType c){printf("%d ",c);}void main(){int j;SqStack s;SElemType e;InitStack(s);for(j=1;j<=12;j++)Push(s,j);printf("栈中元素依次为");StackTraverse(s,print);Pop(s,e);printf("弹出的栈顶元素e=%d\n",e);printf("栈空否:%d(1:空0:否)\n",StackEmpty(s));GetTop(s,e);printf("栈顶元素e=%d 栈的长度为%d\n",e,StackLength(s));ClearStack(s);printf("清空栈后,栈空否:%d(1:空0:否)\n",StackEmpty(s));DestroyStack(s);printf("销毁栈后,s.top=%u s.base=%u s.stacksize=%d\n",s.top,s.base, s.stacksize);}

代码运行的结果:

/*栈中元素依次为1 2 3 4 5 6 7 8 9 10 11 12弹出的栈顶元素e=12栈空否:0(1:空0:否)栈顶元素e=11 栈的长度为11清空栈后,栈空否:1(1:空0:否)销毁栈后,s.top=0 s.base=0 s.stacksize=0Press any key to continue*/

/*栈也是线性表,是操作受限的线性表。栈的操作是线性表操作的子集。因此,也可以将线性表的结构作为栈的结构。例如,可把不带头结点的线性单链表结构(见图212)作为链栈的结构,如图36 所示。这样,线性单链表的一些基本操作(在bo2-8.cpp 中)就可以直接用于链栈的操作了。例如,初始化链表和初始化链栈的操作是一样的,就不必定义InitStack() 函数, 可通过“ #define InitStackInitList ” 命令直接把InitList() 函数当作InitStack()函数使用。同时把栈元素SElemType定义为线性表元素ElemType。线性表的另一些基本操作,如ListInsert()也可以作为栈的基本操作Push()来使用(取特例i=1,即在第1 个元素之前插入)。由于栈的操作被限定仅在栈顶进行,显然,令表头为栈顶可简化栈的操作。教科书对栈的定义是:限定仅在表尾进行插入或删除操作的线性表(教科书44 页)。*/



0 0