首页 > 其他分享 >简单的数据结构:栈

简单的数据结构:栈

时间:2024-07-27 17:25:03浏览次数:12  
标签:capacity top 简单 ST assert STDataType 数据结构 pst

1.栈的基本概念

1.1栈的定义

栈是一种线性表,只能在一端进行数据的插入或删除,可以用数组链表来实现,这里以数组为例进行说明

栈顶 :数据出入的那一端,通常用Top表示

栈底 :相对于栈顶的另一端,也是固定的一端,不允许数据的插入和删除

空栈:不含数据的栈

1.2栈的基本操作

栈的初始化:通常用STInit(&St)表示,用来初始化一个栈St

入栈:一般用STPush(&St, x)表示,给栈St插入数据x,也叫做进栈压栈,同时要注意是否栈满,栈满则需要扩容

出栈:一般用STPop(&St)表示,给栈St删除数据,有时也叫弹栈,需要注意是否栈空

 判断栈空:用STEmpty(&St)表示,常用到判断栈空,因此封装成函数,方便使用,返回值一般用bool类型,true表示栈空,false表示栈非空 

 读栈顶元素:用STTop(&St)表示,栈非空则返回栈顶元素

获取数据个数:用STSize(&St)表示 ,返回数据个数

2.栈的实现 

用一个结构体描述这个栈的各项数据:

typedef int STDataType;

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

初始化栈: 

void STInit(ST* pst)
{
    assert(pst);
    pst->a = NULL;
    //top指向栈顶数据的下一个位置
    pst->top = 0;
    pst->capacity = 0;
}

top可以指向栈顶,也可以指向栈顶的下一个位置,top的指向会影响后续的数据插入、删除、销毁,以及判空 

 栈的销毁:

void STDestroy(ST* pst)
{
    assert(pst);

    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 : pst->capacity* 2; //空栈则让栈空间为4
        STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));
        if (tmp == NULL)
        {
            perror("realloc fail");    
            return;
        }

        pst->a = tmp;
        pst->capacity = newcapacity;
    }
    pst->a[pst->top] = x;
    pst->top++;
}
 

利用realloc的特性,空栈则执行malloc的功能 

出栈:

void STPop(ST* pst)
{
    assert(pst);
    assert(pst->top > 0);   //防止栈空
    pst->top--;
}

 取栈顶数据:

STDataType STTop(ST* pst)
{
    assert(pst);
    return pst->a[pst->top - 1];  //返回值为STDataType
}

判空:

bool STEmpty(ST* pst)
{
    assert(pst);
    return pst->top == 0;
}

获取栈的数据个数:

int    STSize(ST* pst)
{
    assert(pst);
    return pst->top;

3.所有代码 

以数组为例实现栈,分为头文件(Stack.h)和函数实现(Stack.c)以及测试(test.c)

Stack.h:

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.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:

#include"Stack.h"

//初始化栈
void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	//top指向栈顶数据的下一个位置
	pst->top = 0;
	pst->capacity = 0;
}
void STDestroy(ST* pst)
{
	assert(pst);

	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 : pst->capacity* 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));
		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);
	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

#include"Stack.h"
int main()
{
	ST s;
	STInit(&s);
	STPush(&s, 1);
	STPush(&s, 2);
	STPush(&s, 3);
	STPush(&s, 4);
	while (!STEmpty(&s))
	{
		printf("%d\n", STTop(&s));
		STPop(&s);
	}
	STDestroy(&s);
	return 0;
}

 

标签:capacity,top,简单,ST,assert,STDataType,数据结构,pst
From: https://blog.csdn.net/2302_81258662/article/details/140733441

相关文章

  • 【STC 相关】【转载】51单片机学习教程(简单入门)
    转载自:知乎https://zhuanlan.zhihu.com/p/628407258作者:rakey(作者主页https://www.zhihu.com/people/rakey-49) 学习51单片机之前你一定要具备的基础知识。1、C语言基础。2、数字电路基础。3、模拟电路基础。如果你已经具备这些知识那么我们就可以来学习单片机。学习......
  • AP2813宽输入电压5-80V 双路降压恒流LED芯片_外围简单内置功率管驱动IC
    产品描述AP2813是一款双路降压恒流驱动器,高效率、外围简单、内置功率管,适用于5-80V输入的高精度降压LED恒流驱动芯片。内置功率管输出最大功率可达12W,最大电流1.2A。AP2813一路直亮,另外一路通过MODE1切换全亮,爆闪。AP2813工作频率固定在150KHZ左右,同时内置抖频......
  • 数据结构(顺序表)
     ......
  • 【数据结构】二叉树
    目录二叉树特殊二叉树二叉树的性质二叉树的模拟实现存储结构接口实现内部类遍历前序遍历中序遍历后序遍历遍历确定二叉树层序遍历获取节点个数获取叶子节点的个数获取第K层节点的个数获取二叉树的高度检测值为value的元素是否存在判断一棵树是不是完全二叉树练习链接......
  • 数据结构基础第7讲
    数据结构基础第7讲查找考点一:查找的基本概念1.概念静态查找动态查找分类2.查找性能计算平均查找长度:考点二:顺序查找1.顺序查找2.优劣考点三:折半查找(二分搜索)1.概念2.过程3.构建为判定树构建向上取整:左少右多向右偏向下取整:左多右少......
  • 数据结构基础第8讲
    数据结构基础第8讲排序考点一:排序的概念和性能分析1.排序的概念稳定性根据相对位置是否改变判断内排序2.排序的性能考点二:插入类排序1.直接插入排序\(复杂度O(n^2)\)3.折半插入排序改进了比较次数未改变移动次数,因此复杂度仍为\(O(n^2)\)3.希尔排序时......
  • Navicat premium最新【16/17 版本】安装下载教程,图文步骤详解(超简单,一步到位,免费下载
    文章目录软件介绍软件下载安装步骤激活步骤软件介绍Navicat是一款快速、可靠且功能全面的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设计。以下是对Navicat的详细介绍:一、产品概述开发目的:Navicat旨在通过其直观和设计完善的用户界面,帮助数据库管......
  • 数据结构-线性表
    目录王道章节内容知识框架考纲内容引入方法1:顺序存储结构的直接表示方法2:顺序存储结构表示非0项方法3:链表结构存储非零项线性表定义线性表的主要操作(ADT)顺序存储结构定义结构代码实现操作及实现初始化获得查找插入删除链式存储结构单链表定义结构代码......
  • 手撕数据结构---------顺序表和链表
    1.线性表线性表(linearlist)是n个具有相同特性的数据元素的有限序列。线性表是⼀种在实际中⼴泛使⽤的数据结构,常⻅的线性表:顺序表、链表、栈、队列、字符串…线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连续的,线性表在物理上存储时,通常......
  • 【数据结构】:用Java实现链表
    在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移,时间复杂度为O(n),效率比较低,因此ArrayList不适合做任意位置插入和删除比较多的场景。因此:java集合中又引入了LinkedList,即链表结构。概念顺序表是物理上连续,逻辑上也是连续的链表......