线性表------栈

1、基本概念

  • 栈:只允许在一端插入或删除操作的线性表
  • 栈底(buttom):固定的,不允许进行插入和删除操作的另一端
  • 栈顶(top):线性表允许插入和删除的一段
    栈是线性表,只不过受到限制了,只允许在栈顶进行插入和删除操作,所以先入栈的后出栈
    在这里插入图片描述

2、顺序栈

栈是线性表的特例,栈的顺序存储也是线性表顺序存储。栈的顺序存储结构叫做顺序栈,由于栈是受到限制的(只允许在栈顶进行插入和删除),所以顺序栈需要在顺序表是基础上修改点

/*
	顺序栈的定义
*/
#define MaxSize 50		//定义栈中有多少个元素
typedef int ElemType;
typedef struct {
	ElemType data[MaxSize];//存放栈中元素
	int top;		//栈顶指针
}SqStack;

在这里插入图片描述

  • top值不能超过MaxSize
  • 空栈的判断条件top==-1,初始值也是这个值,当没有元素时,top指向buttom后一个元素,满栈的判断条件top==MaxSize-1

2.1 基本操作

2.1.1 判空

/*
	判断空
*/
bool StackEmpty(SqStack S) {
	if (S.top == -1)
		return true;
	else
		return false;
}

2.1.2 进栈
栈不满时,栈顶指针先加1,再送值到栈顶元素

/*
	进栈
*/
bool Push(SqStack& S, ElemType x) {
	if (S.top == MaxSize - 1)
		return false;
	S.data[++S.top] = x;
	return true;
}

2.1.3 出栈
先判断栈是否为空,不为空,取栈顶元素,top减一

/*
	出栈
*/
bool Pop(SqStack& S, ElemType& x) {
	if (S.top == -1)
		return false;
	x = S.data[S.top];
	S.top--;
	return true;
}

2.1.4 读取栈顶元素
栈顶不为空,取栈顶元素

/*
	读取栈顶元素
*/
bool GetTop(SqStack S, ElemType& x)
{
	if (S.top == -1)
		return false;
	x = S.data[S.top];
	return true;
}

3、共享栈

栈底位置相对不变的,可以让两个顺序栈共享一个一维数组,将两个栈的栈底分别设置在共享栈的两端,两个栈顶向共享空间的中间延伸,当一个栈存放数据少,一个栈存放数据多,可以考虑共享栈
在这里插入图片描述

typedef struct {
	ElemType data[MaxSize];		//存放元素
	int top1;					//栈1栈顶
	int top2;					//栈2栈顶
}SqDoubleStack;
  • 初始状态:top1=-1,top2=MaxSize,所以当top1=-1时表示栈1空,top2=MaxSize时,表示栈2空
  • 栈满:当top1和top2相差1时,栈满,此时两个栈的栈顶紧挨着,没有空间存放数据了
  • 出栈:top2加1,top1要减1
  • 入栈:top1加1,top2减1

3.1基本操作

3.1.1 进栈

/*
	进栈
		stackNum:栈的序号

*/

bool Push(SqDoubleStack& S, ElemType x, int stackNum) {
	if (S.top1 + 1 == S.top2)
		return false;	//栈满
	if (stackNum == 1)
		S.data[++S.top1] = x;
	if (stackNum == 2)
		S.data[++S.top2] = x;
	return true;
}

4、链式栈

采用链式存储的栈称为链栈,链栈的优点是便于多个栈共享存储空间和提高其效率,并且不存在栈满溢出的情况,通常采用单链表实现,并规定所有操作都是在单链表的表头进行的
带头结点:

typedef struct SNode {
	ElemType data;			//数据域
	struct SNode* next;	//指针域
} SNode,*SLink;	//链栈的结点
typedef struct LinkStack {
	SLink top;	//栈顶指针
	int count;	//链栈结点数
}LinkStack;	//链栈

不带头结点:

typedef struct SNode {
	ElemType data;			//数据域
	struct SNode* next;	//指针域
} SNode,*SLink;	

注意不带头结点和带头结点的链栈,在具体实现方面有所不同
在这里插入图片描述

扫描二维码关注公众号,回复: 9764273 查看本文章
  • 可以将头指针当做栈顶
  • 空栈的判断条件定为top==null

4.1 基本操作

4.1.1 进栈

/*
进栈
*/
bool Push(LinkStack *S, ElemType x) {
	SLink p = (SLink)malloc(sizeof(SNode));
	p->data = x;
	p->next = S->top;
	S->top = p;
	S->count++;
	return true;

 }

4.1.2 出栈

/*
	出栈
*/
bool Pop(LinkStack* S, ElemType& x) {
	if (S->top == NULL)
		return false;
	x = S->top->data;
	SLink p = S->top;
	S->top = S->top->next;
	free(p);
	S->count--;
	return true;
}
发布了168 篇原创文章 · 获赞 14 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41683305/article/details/104413189