数据结构:6、栈

一、栈的概念

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

如下图所示就是栈的进栈和出栈,全部代码附在文章末。

二、栈的实现

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

 1、栈的初始化与销毁

首先创建一个顺序表,因为栈的原理就是,后进先出,也就是相当于数组,最后一位一个个出去,而先进入的数据在数组的前面,所以就定义成顺序表.

所以定义在初始化中,把容量和栈顶也就是capacity和top这两个变量,但是数组的表示一般都是指向下一位,例如:arr[0]就是第一位数据,所以top定义为0但是他指向的数据的下一位,销毁就是把存放数据的指针a释放,因为是连续的所以释放一次就行了,容量和栈顶赋值为0,代码如下。

typedef int STDatetype;typedef struct Stack
{STDatetype* a;int top;int capacity;
}ST;void StackInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}void StackDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = ps->top = 0;
}

2、判断是否为空

这个函数就是利用bool库函数的实现,当栈顶的数据top为0时就返回真,在外面使用也就是用个取反就可以了。

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

3、进栈与出栈

这个入栈的时候,需要先判定是否还有容量,也就是容量等于栈顶的时候就去申请空间,这里利用了三目运算符,当容量为0时赋值为4,不等于0直接乘上2,然利用realloc申请空间,然后把新的容量和地址分别赋给a和容量,realloc在地址为空时它相当于melloc这时可以运行测试下,测试代码和运行结果如下。

这里是从1到6入栈,但是出栈是后一个个出,所以就是6 5 4 3 2 1,因为这里测试了下判断有用吗,也就是栈为空时不能删,会报错断言。

// 入栈
void StackPush(ST* ps, STDatetype data)
{assert(ps);if (ps->capacity == ps->top){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;ST* newnode = (ST*)realloc(ps->a, newcapacity * sizeof(STDatetype));if (newnode == NULL){perror("recalloc fail");return;}ps->a = newnode;ps->capacity = newcapacity;}ps->a[ps->top] = data;ps->top++;
}// 出栈
void StackPop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));ps->top--;
}

测试代码

void TestStack1()
{ST ST;int temp = 0;int size = 0;StackInit(&ST);StackPush(&ST, 1);StackPush(&ST, 2);StackPush(&ST, 3);StackPush(&ST, 4);StackPush(&ST, 5);StackPush(&ST, 6);temp=StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);StackDestroy(&ST);
}

 

4、获取栈顶的元素与栈的元素个数

差点忘了,上文中测试时,利用了这里才说的获取栈顶元素,因为获取一个删一个打印一下,这里就是获取元素的个数和获取栈顶元素,因为当数据为空时,有效元素个数为0,这里测试就是打印,然后当元素为空时,再去获取就会报错。

// 获取栈顶元素
STDatetype StackTop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->a[ps->top-1];
}// 获取栈中有效元素个数
int StackSize(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->top;
}

测试代码

void TestStack2()
{ST ST;int temp = 0;int size = 0;StackInit(&ST);StackPush(&ST, 1);StackPush(&ST, 2);StackPush(&ST, 3);StackPush(&ST, 4);StackPush(&ST, 5);StackPush(&ST, 6);size = StackSize(&ST);printf("\n%d\n", size);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);size = StackSize(&ST);printf("\n%d\n", size);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);size = StackSize(&ST);printf("\n%d\n", size);StackDestroy(&ST);
}

 

三、代码

ST.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>typedef int STDatetype;typedef struct Stack
{STDatetype* a;int top;int capacity;
}ST;// 初始化栈
void StackInit(ST* ps);
// 入栈
void StackPush(ST* ps, STDatetype data);
// 出栈
void StackPop(ST* ps);
// 获取栈顶元素
STDatetype StackTop(ST* ps);
// 获取栈中有效元素个数
int StackSize(ST* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(ST* ps);
// 销毁栈
void StackDestroy(ST* ps);

ST.c

#define _CRT_SECURE_NO_WARNINGS 1#include "ST.h"// 初始化栈
void StackInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}// 入栈
void StackPush(ST* ps, STDatetype data)
{assert(ps);if (ps->capacity == ps->top){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;ST* newnode = (ST*)realloc(ps->a, newcapacity * sizeof(STDatetype));if (newnode == NULL){perror("recalloc fail");return;}ps->a = newnode;ps->capacity = newcapacity;}ps->a[ps->top] = data;ps->top++;
}// 出栈
void StackPop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));ps->top--;
}// 获取栈顶元素
STDatetype StackTop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->a[ps->top-1];
}// 获取栈中有效元素个数
int StackSize(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->top;
}// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}// 销毁栈
void StackDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = ps->top = 0;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1#include "ST.h"void TestStack1()
{ST ST;int temp = 0;int size = 0;StackInit(&ST);StackPush(&ST, 1);StackPush(&ST, 2);StackPush(&ST, 3);StackPush(&ST, 4);StackPush(&ST, 5);StackPush(&ST, 6);temp=StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);StackDestroy(&ST);
}void TestStack2()
{ST ST;int temp = 0;int size = 0;StackInit(&ST);StackPush(&ST, 1);StackPush(&ST, 2);StackPush(&ST, 3);StackPush(&ST, 4);StackPush(&ST, 5);StackPush(&ST, 6);size = StackSize(&ST);printf("\n%d\n", size);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);size = StackSize(&ST);printf("\n%d\n", size);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);size = StackSize(&ST);printf("\n%d\n", size);StackDestroy(&ST);
}void main()
{TestStack2();return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分类预测 | Matlab实现GSWOA-KELM混合策略改进的鲸鱼优化算法优化核极限学习机的数据分类预测

分类预测 | Matlab实现GSWOA-KELM混合策略改进的鲸鱼优化算法优化核极限学习机的数据分类预测 目录 分类预测 | Matlab实现GSWOA-KELM混合策略改进的鲸鱼优化算法优化核极限学习机的数据分类预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 GSWOA-KELM分类&#xff0…

基于Java的天然气工程业务管理系统(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、使用角色3.1 施工人员3.2 管理员 四、数据库设计4.1 用户表4.2 分公司表4.3 角色表4.4 数据字典表4.5 工程项目表4.6 使用材料表4.7 使用材料领用表4.8 整体E-R图 五、系统展示六、核心代码6.1 查询工程项目6.2 工程物资…

【how2j练习题】css部分课后练习

第一题 <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"> </head><style> body{font-family:"宋体";font-size:13px;color:#666666;width:643px;}.bold{font-weight:bold;}div.t…

C# wpf 使用GDI实现截屏

wpf截屏系列 第一章 使用GDI实现截屏&#xff08;本章&#xff09; 第二章 使用GDI实现截屏 第三章 使用DockPanel制作截屏框 第四章 实现截屏框热键截屏 第五章 实现截屏框实时截屏 第六章 使用ffmpeg命令行实现录屏 文章目录 wpf截屏系列前言一、导入gdi32方法一、NuGet获取…

【框架学习 | 第六篇】SpringBoot基础篇(快速入门、自动配置原理分析、配置文件、整合第三方技术、拦截器、文件上传/下载、访问静态资源)

文章目录 1.SpringBoot简介1.1原有Spring优缺点分析1.1.1Spring优点1.1.2Spring缺点 1.2SpringBoot概述1.2.1SpringBoot解决上述Spring的缺点1.2.2SpringBoot特点1.2.3SpringBoot核心功能 2.SpringBoot快速入门2.1代码实现2.1.1创建Maven工程2.1.2添加SpringBoot的起步依赖2.1.…

走进网络世界 了解一些基础知识

走进网络 1.认识计算机 1.计算机网络是由计算机和通讯构成的&#xff0c;网络研究的是“通信”。 ------1946 世界上第一台计算机 2.终端&#xff1a;只有输入和输出功能&#xff0c;没有计算和处理功能。3.数据&#xff1a;一串数字&#xff08;二进制数&#xff09;&#x…

OpenFeign服务接口调用

OpenFeign服务接口调用 1、OpenFeign简介 ​ Feign是一个声明性web服务客户端。它使编写web服务客户端变得更容易。使用Feign创建一个接口并对其进行注释。它具有可插入的注释支持&#xff0c;包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud添加…

【符号链接】【bash】遍历目录下的每个子项目

为git_repos目录下的每个项目创建符号链接&#xff08;软链接&#xff09;&#xff0c;需要遍历该目录下的每个子项目&#xff0c;并使用ln -s命令为它们分别创建链接。 1. 创建脚本文件 创建一个文本文件来编写你的脚本。这可以通过任何文本编辑器完成&#xff0c;比如nano…

建设IAM/IDM统一身份管理,实现系统之间的单点登录(SSO)

企业实施身份管理的现状&#xff1a; 1.身份存储分散&#xff0c;不能统一供应诸多应用系统&#xff0c;企业用户信息常常存在于多个系统&#xff0c;如HR系统有一套用户信息&#xff0c;OA系统也有一套用户信息&#xff0c;身份存储不集中&#xff0c;不能统一地为诸多应用系…

linux系统docker容器可视化工具portainer

可视化工具portainer portainer可视化工具安装官网安装步骤docker命令安装创建admin登录后&#xff0c;选择local选项卡 中文版本 portainer可视化工具 portainer是一款轻量级应用&#xff0c;他提供图形化界面&#xff0c;用于方便的管理docker环境&#xff0c;包括单机环境和…

Pikachu 靶场搭建

文章目录 1 Pikachu 简介2 Pikachu 安装 1 Pikachu 简介 Pikachu是一个使用“PHP MySQL” 开发、包含常见的Web安全漏洞、适合Web渗透测试学习人员练习的靶场&#xff0c;运行Pikachu需要提前安装好“PHP MySQL 中间件” 的基础环境&#xff0c;可以使用集成软件来搭建&…

React路由结合Material UI的ListItemButton组件完成导航示例

React路由结合Material UI的ListItemButton组件完成导航示例 1、创建菜单列表NavigationList.jsx2、App.js 1、创建菜单列表NavigationList.jsx import React from react; import { ListItemButton, ListItemText, List } from mui/material; import { NavLink as RouterLink …