【数据结构】栈(C语言实现)

news2025/1/22 23:52:47

📙 作者简介 :RO-BERRY
📗 学习方向:致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持


请添加图片描述


  • 1.栈
    • 1.1栈的概念及结构
    • 1.2栈的实现
      • 1.2.1 Stack.h
      • 1.2.2 Stack.c
        • 初始化
        • 入栈
        • 出栈
        • 获取栈顶元素
        • 获取栈中有效元素个数
        • 判空
        • 销毁
    • 1.3 源代码
      • Stack.h
      • Stack.c

1.栈

1.1栈的概念及结构

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

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。

出栈:栈的删除操作叫做出栈。出数据也在栈顶。
这里有一张学长做的图片,我们借鉴来看一下
在这里插入图片描述
在这里插入图片描述


1.2栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。

在这里插入图片描述
在这里插入图片描述
我们接下来将整个栈的函数体实现出来
分为三个文件:

  1. Stack.h (函数头和函数体)
  2. Stack.c (功能具体实现)
  3. Test.c (功能测试)

1.2.1 Stack.h

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

// 下面是定长的静态栈的结构,实际中一般不实用,所以我们主要实现下面的支持动态增长的栈
//typedef int STDataType;
//#define N 10
//typedef struct Stack
//{
//	STDataType a[N];
//	int top; // 栈顶
//}Stack;

// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity; 
}ST;

// 初始化栈
void STInit(ST* ps);

// 入栈
void STPush(ST* ps, STDataType x);

// 出栈
void STPop(ST* ps);

// 获取栈顶元素
STDataType STTop(ST* ps);

// 获取栈中有效元素个数
int STSize(ST* ps);

// 检测栈是否为空
bool STEmpty(ST* ps);

// 销毁栈
void STDestroy(ST* ps);

1.2.2 Stack.c

初始化

我们将队列中容量和个数都置为0,将存储数值的指针变量a置为空

void STInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

入栈
void STPush(ST* ps, STDataType x)
{
	assert(ps);       //先断言判断是否为空
	if (ps->top == ps->capacity)       //如果存储的值个数和容量相等
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2 ;     //容量为0则置为4,不为0则置为原容量的两倍
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);    //开辟新空间
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newCapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;   //数值增加了一个
}

出栈
void STPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	--ps->top;
}

获取栈顶元素
STDataType STTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	return ps->a[ps->top - 1];
}

获取栈中有效元素个数
int STSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

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


销毁
void STDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

1.3 源代码

Stack.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

 下面是定长的静态栈的结构,实际中一般不实用,所以我们主要实现下面的支持动态增长的栈
//typedef int STDataType;
//#define N 10
//typedef struct Stack
//{
//	STDataType a[N];
//	int top; // 栈顶
//}Stack;

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

void STInit(ST* ps);
void STDestroy(ST* ps);
void STPush(ST* ps, STDataType x);
void STPop(ST* ps);
STDataType STTop(ST* ps);
int STSize(ST* ps);
bool STEmpty(ST* ps);

Stack.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
void STInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}
void STDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}
void STPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2 ;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newCapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;
}
void STPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	--ps->top;
}
STDataType STTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	return ps->a[ps->top - 1];
}
int STSize(ST* ps)
{
	assert(ps);
	return ps->top;
}
bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

最后的Test可以自由发挥

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1102109.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Dynamics 365 QueryExpression生成工具

D365后端的查询构建语句有QueryExpression和FetchExpression&#xff0c;一般在涉及多表查询的时候会用FetchExpression多一些&#xff0c;因为结构看起来比较直观&#xff0c;而且生成也有多种方式&#xff0c;比如高级查找构建后下载XML&#xff0c;比如Xrmtoolbox中的fetch …

Unity 3D 基础——Coroutine 协同程序

Coroutine 称为协同程序或者协程&#xff0c;协同程序可以和主程序并行运行&#xff0c;和多线程有些类似。协同程序可以用来实现让一段程序等待一段时间后继续运行的效果。例如&#xff0c;执行步骤1&#xff0c;等待3秒&#xff1b;执行步骤2&#xff0c;等待某个条件为 true…

微信小程序首页-----布局(详细教程赶快收藏吧)

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《Vue.js使用》 ⛺️ 越努力 &#xff0c;越幸运。 1.flex弹性布局 Flex是Flexible Box的缩写&#xff0c;意为”弹性布局”&#xff0c;用来为盒状模型提供最大…

被无视的小细节

最近要写一个web服务,对外提供几个Api,选用gin框架. gin的路由广泛为人好评,一直是"gin为什么这么快"的主角. 正在看其用到的httprouter的源码, 对这种特殊的trie树—基树树(Radix Tree),也有还不错的理解. ( httprouter包只有200多k,非常值得一看 ) 就在自以为洞若观…

linux虚机新增加磁盘后在系统中查不到

问题描述 在虚机管理平台上对某一linux主机添加了一块硬盘&#xff0c;但在系统中并未显示 通过执行 lsblk&#xff0c;并未看到新增的硬盘信息 解决方法 1. 可通过重启服务器解决 2. 如果不能重启服务器&#xff0c;可重新扫描下 scsi总线 查看总线&#xff1a; ls /s…

那些年,我们追过的Go BUG

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

多媒体应用设计师 第9章 信息安全性知识

1.信息安全性基本概念 2.计算机病毒防范 2.1.计算机病毒的分类与识别 病毒特点&#xff1a;隐蔽性&#xff0c;传染性&#xff0c;破坏性&#xff0c;潜伏性 计算机病毒构成:感染标志(病毒签名)&#xff0c;引导模块&#xff0c;感染模块&#xff0c;破坏模块(表现模块) 病…

机器学习算法 —— 1. K近邻算法

K近邻算法 1. K近邻算法简介2. K近邻算法常见距离度量2.1 欧氏距离&#xff08;Euclidean Distance&#xff09;2.2 曼哈顿距离&#xff08;Manhattan Distance &#xff09;2.3 切比雪夫距离&#xff08;Chebyshev Distance&#xff09;2.4 闵可夫斯基距离&#xff08;Minkows…

PCLVisualizer显示点云的深层用法

以下代码均是在QT中使用QVTKOpenGLNativeWidget的简单教程以及案例-CSDN博客文章的基础上&#xff0c;修改按钮对应的槽函数中的程序。 1.显示文件中点云颜色属性信息&#xff0c;利用PointCloudColorHandlerRGBField得到每个点云对应的颜色。 pcl::PointCloud<pcl::PointX…

vue3学习(十)--- 依赖注入Provide 和 Inject

文章目录 Provide 和 Inject兄弟组件通信Event BusMitt库 Provide 和 Inject provide 可以在祖先组件中指定我们想要提供给后代组件----子、孙等组件的数据或方法&#xff0c;而在任何后代组件中&#xff0c;我们都可以使用 inject 来接收 provide 提供的数据或方法。 父组件…

yield方法的使用

yield的作用就是主动释放CPU的执行权,会将线程从运行状态转为就绪状态,让后调度执行其他线程 使用方法如下: public class YieldTest {public static void main(String[] args) {ThreadTest t1 new ThreadTest("张三");ThreadTest t2 new ThreadTest("李四&q…

设计师首选:最佳的5款网页设计软件

对于UI设计师来说&#xff0c;网页设计是一项必要的技能。如何做好网页设计&#xff1f;除了设计理念&#xff0c;网页设计和制作软件的应用也是不可或缺的。目前市场上有很多这样的软件&#xff0c;工人要想做好&#xff0c;就必须先磨利工具。如果他们想做网页设计&#xff0…

14. Java多线程基础

Java —— 多线程 1. 线程与进程1.1 线程生命周期1.2 线程优先级 2. 多线程2.1 守护线程2.2 多线程高并发2.3 synchronized同步锁2.4 synchronized互斥锁 1. 线程与进程 进程&#xff08;Process&#xff09; 操作系统进行资源分配和调度的基本单位&#xff1a;系统中正在运行的…

复制活动工作表和计数未保存工作簿进行

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。可以大大提高自己的劳动效率&#xff0c;而且可以提高数据的准确性。我这里专注VBA,将我多年的经验汇集在VBA系列九套教程中。 作为我的学员要利用我的积木编程思想&#xff0c;积木编程最重要的是积木如何搭建…

基于springboot实现酒店管理系统平台项目【项目源码+论文说明】计算机毕业设计

摘要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存…

C++算法前缀和的应用:分割数组的最大值的原理、源码及测试用例

分割数组的最大值 相关知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例&#xff1a;付视频课程 二分 过些天整理基础知识 题目 给定一个非负整数数组 nums 和一个整数 m &#xff0c;你需要将这个数组分成 m 个非空的连续子数组。 设计一个算法…

【前端学习】—bind、call、apply(四)

【前端学习】—bind、call、apply(四) 一、代码题 <script>var name="freeman";function sayAuthor(){var name=

2023.10(u盘刻录iso)主机,vmware,virtualbox安装linux/ubuntu/kali

download 1 kali官网 2 ubuntu官网 3vmware workstation pro(最新版17pro) 4 virtualbox for linux sudo apt install virtualbox-ext-pack 5 win32 disk imger linux dd 刻录iso到u盘 #查看U盘路径 fdisk -l #图形界面 以kali为例会在桌面出现挂载图标 点开之后输入pwd寻…

【Android】 屏幕录制screenrecord为什么这么快?

背景 正常的合成视频是个什么样流程? 主要有三大类方法&#xff1a;MediaMux硬解码&#xff0c;mp4parser&#xff0c;FFmepg三种方式详情传送门, 但是并不能把高帧率、分辨率屏幕视频实时保存下来 那么Android screenrecord命令是怎么做的呢&#xff1f; 一般的android图像流…

【开发心得】Jaxb使用珠玑

前言 Java操作xml转换成javaBean,或者javaBean转换为xml的方式有很多。常见的有dom4j等工具直接操作dom&#xff0c;或者使用jaxb. jaxb介绍: JAXB(Java Architecture for XML Binding简称JAXB)允许Java开发人员将Java类映射为XML表示方式。JAXB提供两种主要特性&#xff1a;…