【数据结构】栈和队列2——栈的表示和实现


栈的抽象数据类型定义

ADT Stack{
	数据对象:D={ai|ai∈ElemSet,i=1,2,,n,n≥0}
	数据关系:R1={<ai-1,ai>|ai-1,ai∈D,i=2,,n}
			约定an端为栈顶,a1端为栈底
	基本操作:初始化、进栈、出栈、取栈顶元素等
			InitStack(&S)  初始化操作
			操作结果:构造一个空栈S。
			DestroyStack(&S)  销毁栈操作
			初始条件:栈S已存在。
			操作结果:栈S被销毁。
			StackEmpty(S)  判定S是否为空栈
			初始条件:栈S已存在。
			操作结果:若栈S为空栈,则返回TRUE,否则FALSE。
			Stacklength(S)  求栈的长度
			初始条件:栈S已存在。
			操作结果:返回S的元素个数,即栈的长度。
			GetTop(S, &e)  取栈顶元素
			初始条件:栈S已存在且非空。
			操作结果:用e返回S的栈顶元素。
			ClearStack(&S)  栈置空操作
			初始条件:栈S已存在。
			操作结果:将S清为空栈。
			Push(&S, e)  入栈操作
			初始条件:栈S已存在。
			操作结果:插入元素e为新的栈顶元素。
			Pop(&S, &e)  出栈操作
			初始条件:栈S已存在且非空。
			操作结果:删除S的栈顶元素an,并用e返回其值。
}ADT Stack

栈的表示和实现

实现方式:由于栈本身就是线性表,于是栈也有顺序存储和链式存储两种实现方式。
栈的顺序存储——顺序栈
钱的链式存储——链栈

顺序栈

栈的顺序存储——顺序栈

顺序栈的表示

存储方式:同一般线性表的顺序存储结构完全相同,利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。栈底一般在低地址端。
① 附设top指针,指示栈顶元素在顺序栈中的位置。
② 另设base指针, 指示栈底元素在顺序栈中的位置。
③ 另外,用stacksize表示栈可使用的最大容量

为了方便操作,通常top指示真正的栈顶元素之上的下标地址,不是最大下标(stacksize-1)
在这里插入图片描述

在这里插入图片描述
使用数组作为顺序栈存储方式的特点:
简单方便、但易产生溢出(数组大小固定)
上溢(overflow):栈已经满,又要压入元素
下溢(underflow):栈已经空,还要弹出元素

注:上溢是一种错误,使问题的处理无法进行;而下溢十般认为是一种结束条件,即问题处理结束。

顺序栈的实现

顺序栈的数据类型定义:

#define maxsize 100
typedef struct{
	SElemType *base;//栈底指针
	SElemType *top;//栈顶指针
	int stacksize;//栈可用最大容量
}SqStack;

顺序栈的图示:
在这里插入图片描述
顺序栈基本操作的实现
1、顺序栈的初始化
在这里插入图片描述

Status InitStack(SqStack &S){
	S.base=new SElemType[maxsize];//或s.base=(SElemType*)malloc(maxsize*sizeof(SElemType));
	if(!S.base)
		exit(overflow);//存储分配失败
	S.top=S.base;//栈顶指针等于栈底指针
	S.stacksize=maxsize;
	return ok;
}

2、属性栈判断是否为空
在这里插入图片描述

status StackEmpty(SqStack S){//若栈为空,返回true,否则返回false
	if(S.top==S.base)
		return ture;
	else
		return false;
}

2、求顺序表的长度
在这里插入图片描述

int StackLength(SqStack S){
	return S.top-S.base;
}

3、清除顺序表
在这里插入图片描述

Status ClearStack(SqStack S){
	if(S.base)
		S.top=S.base;
	return ok;
}

4、销毁顺序表
在这里插入图片描述

Status DestroyStack(SqStack &S){
	if(S.base)
		delete S.base;
		S.stacksize=0;
		S.base=S.top=null;
	return ok;
}

5、顺序表的入栈
【算法思路】
① 判断是否栈满,若满则出错(上溢)
② 元素e压入栈顶
③ 栈顶指针加1
在这里插入图片描述

Status Push(SqStack &S,SElemType e){
	if(S.top-S.base==S.stacksize)//栈满
		return error;
	S.top++=e;//同 *S.top=e; S.top++;
	return ok;
}

6、顺序栈的出栈
① 判断是否栈空,若空则出错(下溢)
② 栈顶指针减1
③ 获取栈顶元素e
在这里插入图片描述

Status Pop(SqStack &S,SElemType &e){//若栈不空,则删除S的栈顶元素,用e返回其值,并返回ok
	if(S.top==S.base)//等价于if(StackEmpty(S))
		return error;
	e=*--S.top;//同 --S.top; e=*S.top;
	return ok;
}

链栈

钱的链式存储——链栈

链栈的表示

存储方式:链栈是运算受限的单链表,只能在链表头部进行操作。
① 链表的头指针就是栈顶;
② 不需要头结点;
③ 基本不存在栈满的情况;
④ 空栈相当于头指针指向空;
⑤ 插入和删除仅在栈顶处执行。
在这里插入图片描述

typedef struct StackNode{
	SELemType data;
	struct StackNode *next;
}StackNode,*LinkStack;//定义的这个结构是StackNode类型,再用这个类型定义一个指向*LinkStack结点的指针类型
LinkStack S;//用S来表示stack栈,这个栈是指向这个结点的指针型

链栈的实现

1、链栈的初始化

void InitStack(LinkStack &S){//构造一个空栈,栈顶指针置为空
	S=NULL;
	return ok;
}

2、判断链栈是否为空

Status StackEmpty(LinkStack S){//头指针S为空链栈就为空
	if(S==NULL)
		return true;
	else
		return false
}

3、链栈的入栈
在这里插入图片描述

Status Push(LinkStack &S,SElemType e){
	p=new StackNode;//生成新结点p
	p->data=e;//将新结点数据域置为e
	p->next=S;//将新结点插入栈顶
	S=p;//修改栈顶指针
	return ok;
}

4、链栈的出栈
在这里插入图片描述

Status Pop(LinkStack &S,SElemType &e){//删除的值用e返回
	if(S==NULL)
		return error;
	e=S->data;
	p=S;
	S=S->next;
	delete p;
	return ok;
}

5、取栈顶元素
在这里插入图片描述

SElemType GetTop(LinkStack S){
	if(S!=NULL)
		return S->data;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值