栈的表示和实现

// c3-1.h 栈的顺序存储结构(见图3.1)
#define STACK_INIT_SIZE 10 // 存储空间初始分配量
#define STACK_INCREMENT 2 // 存储空间分配增量
struct SqStack
{
	SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
	SElemType *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;否则返回FALSE
	if(S.top==S.base)
		return TRUE;
	else
		return FALSE;
}
int StackLength(SqStack S)
{ // 返回S的元素个数,即栈的长度
	return S.top-S.base;
}
Status GetTop(SqStack S,SElemType &e)
{ // 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
	if(S.top>S.base)
	{
		e=*(S.top-1);
		return OK;
	}
	else
		return 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=0
Press any key to continue

*/

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



posted @ 2014-08-14 22:56  meiyouor  阅读(273)  评论(0编辑  收藏  举报