栈及栈的顺序存储结构的实现

在之前讲解了线性表的链式存储顺序存储以及静态链表循环链表和双向链表我们只需了解即可,接下来我们讲解线性表的应用“

栈是限定仅在表尾进行插入和删除操作的线性表

我们吧允许插入和删除的一端称为栈顶,另一端称为栈底,不含任何数据元素的栈我们称为空栈,栈又称为后进先出的线性表,简称为LIFO结构,可以理解为给枪的弹夹装子弹,后装的子弹会被先发射出去

既然栈是线性表的一种,线性表有顺序存储和链式存储两种结构,那么栈也就有这两种结构

栈的顺序存储结构

在栈的顺序存储中我们用下标为0的一端来作为栈底,定义一个变量top变量来指示栈顶元素在数组中的位置,这个top就类似游标卡尺的游标,可以来回移动,top的值必须小于栈的长度StackSize,当栈存在一个元素时,top等于0,因此通常把空栈的判定条件定位top等于-1

栈的结构

# define MAXSIZE 1000
# define OK 1
# define ERROR 0
# define TRUE 1
# define FALSE 0

typedef int SElemType;           //SElemType就是线性表中的元素的类型,这里设置为int
typedef int Status;
typedef struct{
	SElemType data[MAXSIZE];
	int top;
} SqStack;

进栈操作

Status Push(SqStack *S, SElemType e){
	if(S->top == MAXSIZE - 1){     //栈满 
		return ERROR;
	}
	S->top++;                      //栈顶指针增加1 
	S->data[S->top] = e;           //将新元素放入栈顶指针所指向空间中 
	return OK;
}

出栈操作

Status Pop(SqStack *S, SElemType *e){
	if(S->top == -1){
		return ERROR;
	}
	*e =  S->data[S->top];          //取出栈顶元素 
	S->top--;                       //栈顶指针减少1 
	return OK;
}

进栈和出栈这两种操作都是将之前的线性表的顺序存储进行简单的改进,非常简单,这里不做过多讲解

两栈共享空间

栈的顺序存储非常方便,只从栈顶进栈和出栈,不存在插入数据后对后续数据的移动,但是和线性表的顺序存储存在相同的问题,就是栈的大小必须提前规定好,如果空间不够用了就必须使用编程手段来对空间进行扩充

如果现在有两个栈,可能会存在一种情况:一个栈已经满了,再存入数据就溢出了,而另外一个栈还有剩余的存储空间,我们怎样解决这样的问题?

我们可以使用一个数组来存储两个栈,但是需要一些小技巧:我们让数组的两个端点来分别作为两个栈的栈底,这样我们在两个栈中增加元素时两个栈顶指针就是从数组的两端点想中间移动,只要两个栈顶指针不相遇那么我们就可以一直向栈中存储数据

这里我们定义两个栈,分别为栈1和栈2,栈1为空时top1等于-1,栈2为空时top2等于n,n就是我们预先定义的数组长度,两栈的共享空间定义为:

typedef struct{
	SElemType data[MAXSIZE];
	int top1;
	int top2;
} SqDoubleStack;

当我们在这个栈中进行push时,需要一个判断是栈1还是栈2的参数stackNumber,push方法实现如下:

Status Push(SqDoubleStack *S, SElemType e, int stackNumber){
	if(S->top1 + 1 == S->top2){     //栈已满 
		return ERROR;
	}
	if(stackNumber == 1){
		S->data[++S->top1] = e;
	}else if(stackNumber == 2){
		S->data[--S->top2] = e;
	}
	return OK;
}

在编写push的代码实现的时候主要需要注意的是就是判断栈满,若栈不满则后续的操作很简单,不需要担心两个栈顶指针溢出

接下来讲解pop操作的代码实现:

Status Pop(SqDoubleStack *S, SElemType *e, int stackNumber){
	if(stackNumber == 1){
		if(S->top1 == -1){
			return ERROR;
		}
		*e = S->data[S->top1--];
	}
	else if(stackNumber == 2){
		if(S->top2 == MAXSIZE){
			return ERROR;
		}
		*e = S->data[S->top2++];
	}
}

Pop的代码实现主要需要注意的是判断栈是否空,若栈不空则后续操作很简单,不需要担心两个栈顶指针溢出

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值