第三章 栈与队列(一)

栈得定义:栈(stack)是限定仅在表尾进行插入和删除操作的线性表
我们把允许插入和删除得一端称为栈顶(top),另一端称为栈底,不含任何数据元素得栈称为空栈。栈又称后进先出(Last In First Out)的线性表,简称LIFO结构。
栈首先是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系,只不过它是一种特殊的线性表而已。它的特殊之处就在于限制了这个线性表的插入和删除位置,它始终在栈顶进行。这也就使得:栈底是固定的,最先进栈的只能在栈底。
栈的插入操作,叫做进栈,也称压栈、入栈。
栈的删除操作,叫做出栈,也有的叫做弹栈。

如下图:
进栈
在这里插入图片描述
出栈
在这里插入图片描述

栈的抽象数据类型
ADT 栈(stack)
Data
	同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系
Operation
	InitStack(*S):初始化操作,建立一个空栈S
	DestoryStack(*S):若栈存在,销毁他
	ClearStack(*S):将栈清空
	StackEmpty(S):若栈为空,返回true,否则返回false
	GetTop(*S,e):若栈存在且非空,用e返回S的栈顶元素
	Push(*S,e):若栈S存在,插入新元素e到栈S中并称为栈顶元素。
	Pop(*S,e):删除栈S中栈顶元素,并用e返回其值
	StackLength(S):	返回栈S的元素个数
endADT	
栈的顺序存储结构及实现

栈的顺序存储结构:
栈的定义

typedef int SElemType;         //SElemType类型根据实际情况而定,这里假设为int
typedef struct{
	SElemType data[MAXSIZE];
	int top;                   //指向栈顶
}sqstack;

栈的顺序存储结构–进栈操作
在这里插入图片描述
因此对于进栈操作push,其代码如下

//插入新元素e为新的栈顶元素
Status Push(sqstack *s,SElemType e){
	if(s->top == MAXSIZE-1){
		return ERROR;       //栈已满
	}
	s->top++;
	s->data[s->top]=e;      //将e赋值给栈顶空间
	return ok;
}

栈的顺序存储结构–出栈操作

Status Pop(SqStack *S,SElemType *e){
	if(S->top == -1)
		return ERROR;
	*e = S->data[S->top];      //将要删除的栈顶元素赋值给e
	S->top --;                 //栈顶指针减一
	return ok;	
}
两栈共享空间

其实栈的顺序存储还是很方便的,因为它只准栈顶进出元素,所以不存在线性表插入和删除时需要移动元素的问题。不过它有一个很大的缺陷,就是必须事先确定数组存储空间大小,万一不够用了,就需要编程手段来扩展数组的容量。对于一个栈,只能考虑周全,设计出合适大小的数组来处理,但对于两个相同类型的栈,可以做到最大限度的利用其事先开辟的存储空间来操作。
数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为0处,另一个栈为数组的末端,即下标为数组的长度n-1处。这样,如果两个栈增加元素,就是两端点向中间延伸。
如下图:
在这里插入图片描述
其实关键思路就是:他们是在数组的两端,向中间靠拢。top1和top2是栈1和栈2的栈顶指针,可以想象,只要它两不见面,两个栈就可以一直使用。
两栈共享空间的结构代码如下:

//两栈共享空间的结构代码如下
typedef struct{
	SElemType data[MAXSIZE];
	int top1;
	int top2;
}sqDoubleStack;

对于两栈共享空间的push方法,我们除了要插入元素值参数外,还需要有一个判断是栈1还是栈2的栈号参数stackNumber,插入代码如下

Status Push(sqDoubleStack *s,ElemType e,int stackNumber){
	if(s->top1+1==s->top2)    //栈已满,不能在push新的元素
		retuen  ERROR;
	if(stackNumber=1)
		s->data[++s->top1]=e; //若栈1则先top+1后给数组元素赋值
	else if(stackNumber=2)
		s->data[--s->top2]=e; //若栈2则先top2-1后给数组元素赋值
	return ok;		
}

对于两栈共享空间pop方法

Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber){
	if(stackNumber = 1){
		if(S->top1==-1)
			return ERROR;       //说明栈1是空栈,溢出
		*e=S->data[S->top1--];	//将栈1的栈顶元素出栈
	}
	else if(stackNumber = 2){
		if(S->top2==MAXSIZE){
			return ERROR;       //说明栈2是空栈
		*e=S->data[S->top2++];	//将栈2的栈顶元素出栈
		}
	}
	return ok;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值