数据结构栈

Posted 蓝乐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构栈相关的知识,希望对你有一定的参考价值。

1.基本概念

首先用一张图来大致认识栈
在这里插入图片描述

(1)定义:只允许在一端进行插入或删除操作的线性表。

(2)重要术语

栈顶:允许插入和删除的一端
栈底:不允许插入和删除的一端
空栈:栈中不含元素
在这里插入图片描述

(3)基本操作

InitStack(&S):初始化栈,构造一个空栈S,分配内存空间。
DestroyStack(&S):销毁栈,销毁并释放栈S所占用的内存空间。
Push(&S,x):进栈,若栈S未满,则将x加入使之成为新栈顶。
Pop(&S,&x):出栈,若栈S非空,则弹出栈顶元素,并用x返回。
GetTop(S,&x):读栈顶元素,若栈S非空,则用x返回栈顶元素。
StackEmpty(S):判断一个栈S是否为空。若为空,则返回true,否则返回false。

2.实现方式

(1)顺序存储–顺序栈

顺序栈的定义

#define MaxSize 10//定义栈中元素的最大个数

typedef struct SequenceStack
{
	int data[MaxSize];//静态数组存放栈中元素
	int top;//栈顶“指针”
}Stack;

注意这里的top不是指针变量,而是存放栈顶元素的下标的一个变量。

【拓展】共享栈

即两个栈共享一片空间。
在这里插入图片描述

#define MaxSize 10
typedef struct{
int data[MaxSize];
int top0;//0号栈存放栈顶指针
int top1;//1号栈存放栈顶指针
}ShStack;
//初始化栈
void InitStack(ShStack* S)
{
S->top0=-1;//初始化栈顶指针
S->top1=MaxSize;
}

栈满条件:top0 + 1 == top1

(2)链式存储–链栈

链栈的定义(带头结点)

typedef struct LinkStack
{
	int data;
	struct LinkStack* next;
}Stack;

3.基本操作

(1)顺序栈

a.初始化栈

void InitStack(Stack* S)
{
	S->top = -1;//初始化栈顶指针
}

由于静态数组的下标是从0开始的,故初始化栈时,栈顶指针置为-1,表示栈为空栈。

b.判断栈空

bool EmptyStack(Stack* S)
{
	if (S->top == -1)
		return true;//栈空
	else
		return false;//不空
}

c.进栈操作

与顺序表类似,只不过元素只能从栈顶增加进入栈

bool Push(Stack* S, int x)
{
	if (S->top == MaxSize - 1)//栈满,报错
		return false;
	S->data[++S->top] = x;//先指针+1,再新元素入栈
	return true;
}

d.出栈操作

注意这里的出栈操作后,数据还残留再内存中,只是逻辑上被删除了

bool Pop(Stack* S, int* x)
{
	if (S->top == -1)//栈空,报错
		return false;
	*x = S->data[S->top--];//先栈顶元素出栈,再top-1
	return true;
}

在这里插入图片描述

e.读栈顶元素操作

与出栈操作类似,只不过top不需要改变

bool GetTop(Stack* S, int* x)
{
	if (S->top == -1)
		return false;
	*x = S->data[S->top];//x记录栈顶元素
	return true;
}

(2)链栈(带头结点)

由于链栈与链表并无本质区别,只是在进栈和出栈操作中被限制只能在链表的头部进行插入和删除,故对于链栈的基本操作不作过多的叙述,直接上代码:

a.初始化栈

bool InitStack(Stack* S)//初始化栈
{
	S->next = NULL;
	return true;
}

b.判断栈空

bool EmptyStack(Stack* S)//判断栈空
{
	if (S->next == NULL)
		return true;
	else
		return false;
}

c.进栈操作

bool Push(Stack* S, int x)//进栈操作(头插法)
{
	Stack* p = (Stack*)malloc(sizeof(Stack));
	if (p == NULL)//内存已满,分配空间失败
		return false;
	p->data = x;
	p->next = S->next;
	S->next = p;
	return true;
}

d.出栈操作

bool Pop(Stack* S, int* x)//出栈出栈(头删法)
{
	if (S->next == NULL)
		return false;
	Stack* p = (Stack*)malloc(sizeof(Stack));
	p = S->next;
	*x = p->data;
	S->next = p->next;
	free(p);
	return true;
}

e.读取栈顶元素

bool GetElem(Stack* S, int* x)//获取栈顶元素
{
	if (S->next == NULL)
		return false;
	Stack* p = S->next;
	*x = p->data;
	return true;
}

以上是关于数据结构栈的主要内容,如果未能解决你的问题,请参考以下文章

方法与对象内存分析

Android Studio - 带回栈的导航抽屉

使用callstack在C中实现栈数据结构?

VSCode自定义代码片段5——HTML元素结构

VSCode自定义代码片段5——HTML元素结构

VSCode自定义代码片段5——HTML元素结构