【数据结构】实现栈

大家好,我是苏貝,本篇博客带大家了解栈,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️


目录

一 .栈的概念及结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底 。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
出栈:栈的删除操作叫做出栈,出数据也在栈顶


二 .栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些,因为数组在尾上插入数据的代价比较小(数组的尾插、尾删很方便)。所以下面我们用数组来实现

1

栈的结构体

c 复制代码
typedef int STDataType;
#define N 10
typedef struct Stack
{
 STDataType _a[N];
 int top; // 栈顶
}ST;

上面是定长的静态栈的结构,实际中一般不实用,所以我们主要实现下面的支持动态增长的栈

c 复制代码
typedef int STDataType;

typedef struct Stack
{
	STDataType* a;
	int top;//栈顶
	int capacity;//容量
}ST;

2

初始化

因为我们要对ST类型的变量进行初始化,所以实参要传ST类型变量的地址,用一级指针来接收。因为实参(ST类型变量的地址)不可能为NULL,所以对它断言(下面的接口同理)。

注意:我们这里的top指的是栈顶元素的下一个,而非栈顶元素,所以将它初始化为0

c 复制代码
void STInit(ST* pst)
{
	assert(pst);

	pst->a = NULL;
	pst->capacity = 0;
	pst->top = 0;//指向栈顶元素的下一个
}

3

销毁

注意:在这里我们使用的是动态开辟内存,所以要在销毁时释放掉动态开辟的内存,也就是pst->a指向的那个数组

c 复制代码
void STDestroy(ST* pst)
{
	assert(pst);

	if (pst->a != NULL)
	{
		free(pst->a);
		pst->a = NULL;
		pst->capacity = 0;
		pst->top = 0;
	}
}

4

栈顶插入

再插入元素之前我们要先判断是否要增容,因为在初始化时我们将pst->capacity初始化为0,所以在增容时要特别注意将pst->capacity==0的情况。还要注意对realloc的结果进行判断,防止realloc失败返回NULL,又直接将NULL赋值给pst->a,这样就再找不到开辟的数组了。

最后不要忘记pst->top++

c 复制代码
void STPush(ST* pst, STDataType x)
{
	assert(pst);

	//判断是否需要增容
	if (pst->top == pst->capacity)
	{
		int newcapacity = (pst->capacity == 0) ? 4 : 2 * pst->capacity;
		ST* tmp = (ST*)realloc(pst->a, newcapacity * sizeof(ST));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		pst->a = tmp;
		pst->capacity = newcapacity;
	}

	//插入数据
	pst->a[pst->top] = x;
	pst->top++;
}

5

栈顶删除

删除时我们必须保证栈内有元素,所以要对pst->top>0断言,如果top==0,表示栈内已无元素,返回错误信息,下面的显示栈顶元素同理

c 复制代码
void STPop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);

	pst->top--;
}

6

显示栈顶元素

c 复制代码
STDataType STTop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);

	return pst->a[pst->top - 1];
}

7

是否为空

c 复制代码
bool STEmpty(ST* pst)
{
	assert(pst);

	return pst->top == 0;
}

8

栈的大小

c 复制代码
int STSize(ST* pst)
{
	assert(pst);

	return pst->top;
}

三. 模块化代码实现

Stack.h

c 复制代码
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>

typedef int STDataType;

typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;


//初始化
void STInit(ST* pst);
//销毁
void STDestroy(ST* pst);
//栈顶插入
void STPush(ST* pst, STDataType x);
//栈顶删除
void STPop(ST* pst);
//显示栈顶元素
STDataType STTop(ST* pst);
//是否为空
bool STEmpty(ST* pst);
//大小
int STSize(ST* pst);

Stack.c

c 复制代码
#include"Stack.h"

//初始化
void STInit(ST* pst)
{
	assert(pst);

	pst->a = NULL;
	pst->capacity = 0;
	pst->top = 0;//指向栈顶元素的下一个
}

//销毁
void STDestroy(ST* pst)
{
	assert(pst);

	if (pst->a != NULL)
	{
		free(pst->a);
		pst->a = NULL;
		pst->capacity = 0;
		pst->top = 0;
	}
}

//栈顶插入
void STPush(ST* pst, STDataType x)
{
	assert(pst);

	//判断是否需要增容
	if (pst->top == pst->capacity)
	{
		int newcapacity = (pst->capacity == 0) ? 4 : 2 * pst->capacity;
		ST* tmp = (ST*)realloc(pst->a, newcapacity * sizeof(ST));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		pst->a = tmp;
		pst->capacity = newcapacity;
	}

	//插入数据
	pst->a[pst->top] = x;
	pst->top++;
}

//栈顶删除
void STPop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);

	pst->top--;
}

//显示栈顶元素
STDataType STTop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);

	return pst->a[pst->top - 1];
}

//是否为空
bool STEmpty(ST* pst)
{
	assert(pst);

	return pst->top == 0;
}

//大小
int STSize(ST* pst)
{
	assert(pst);

	return pst->top;
}

Test.c

c 复制代码
#include"Stack.h"

int main()
{
	ST s;
	STInit(&s);
	STPush(&s, 1);
	STPush(&s, 2);
	STPush(&s, 3);
	STPush(&s, 4);
	STPush(&s, 5);

	while (!STEmpty(&s))
	{
		printf("%d  ", STTop(&s));
		STPop(&s);
	}
	printf("\n");

	return 0;
}

结果演示


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

相关推荐
pianmian12 小时前
python数据结构基础(7)
数据结构·算法
ChoSeitaku5 小时前
链表交集相关算法题|AB链表公共元素生成链表C|AB链表交集存放于A|连续子序列|相交链表求交点位置(C)
数据结构·考研·链表
偷心编程5 小时前
双向链表专题
数据结构
香菜大丸5 小时前
链表的归并排序
数据结构·算法·链表
jrrz08285 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
@小博的博客5 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
泉崎7 小时前
11.7比赛总结
数据结构·算法
你好helloworld7 小时前
滑动窗口最大值
数据结构·算法·leetcode
JSU_曾是此间年少8 小时前
数据结构——线性表与链表
数据结构·c++·算法
sjsjs119 小时前
【数据结构-合法括号字符串】【hard】【拼多多面试题】力扣32. 最长有效括号
数据结构·leetcode