数据结构栈和堆列

目录

栈:

栈的概念:

栈的实现:

栈接口的实现:

1.初始化栈:

2.入栈:

3.出栈:

4. 获取栈顶元素:

5.获取栈中有效数据的个数:

 6.检测栈是否为空,如果为空返回非零结果,如果不为空返回0:

 7.销毁栈:

队列:

队列的概念:

队列的实现:

接口的实现:

1.初始化队列:

2. 队尾入队列:

3.队头出队列:

4.获取队列头部元素:

 5.获取队列尾元素:

6.获取队列中有效数据个数:

7.检测队列是否为空,如果为空返回非零结果,如果非空返回0:

8.销毁队列:


栈:

栈的概念:

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

  • 压栈:栈的插入操作叫做进栈/入栈,入数据在栈顶
  • 出栈:栈的删除操作叫做出栈。出数据也在栈顶

栈的实现:

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

C语言单链表-CSDN博客  C语言实现顺序表(增,删,改,查)-CSDN博客 0基础小白学C语言看这一篇就够了(C语言详讲万字!!!)_用c++设计一个程序,实现输入任意一个数(不大于10的5次方),计算从1加到这个数-CSDN博客

栈接口的实现:

栈和顺序表一样,可以做成动态的也可以做成静态的,因为静态的一般是用在那种给定长度的地方,所以这里使用动态的实现栈。

实现之前我们需要各个文件,分别是头文件"Stack.h",以及两个源文件"Stack.c"和"Test.c",他们的作用如下:

  • Stack.h:栈的结构体,头文件引用,接口函数的声明。
  • Stack.c:接口函数的实现。
  • Test.c:测试各个函数的功能。

如下我们先来展示各种接口的声明Stack.h:

#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>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);
1.初始化栈:

把传递进来的第一个栈的置空和值为0

void STInit(ST* ps) {assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}
2.入栈:

入栈之前判断栈的大小是否足够,如果足够那么直接将数据存入对应的位置然后有效值++就行,如果空间不够那么需要扩容,如果扩容失败直接报错误信息。

void STPush(ST* ps, STDataType x) {assert(ps);if (ps->top==ps->capacity) {int newCapacity = ps->capacity * 2 == 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++;
}
3.出栈:

首先断言以下以免出现栈都没有还在出栈,然后有效数据减减就行了。

void STPop(ST* ps) {assert(ps);assert(ps->top > 0);--ps->top;
}
4. 获取栈顶元素:

直接返回数据没啥好说的。

STDataType STTop(ST* ps) {assert(ps);assert(ps->top > 0);return  ps->a[ps->top - 1];
}
5.获取栈中有效数据的个数:

直接返回栈顶元素。

int STSize(ST* ps) {assert(ps);return ps->top;
}
 6.检测栈是否为空,如果为空返回非零结果,如果不为空返回0:

返回类型是一个布尔型也就是不是false就是true。

bool STEmpty(ST* ps) {assert(ps);return ps->top == 0;
}
 7.销毁栈:

把栈释放之后然后把指针置空,值值为0.

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

如下是全代码的示例Stack.c:

#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 * 2 == 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.c文件测试整个代码运行是否正常:

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

队列:

队列的概念:

队列:只允许一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)入队列:进入插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头

队列的实现:

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

接口的实现:

我们首先创建一个头文件"Queue.h"和两个源文件分别是"Queue.c"跟"Test.c",他们的作用为:

  • Queue.h:头文件的引用接口函数的声明,以及栈的结构体。
  • Queue.c:接口的实现。
  • Test.c:测试每个接口。

如下代码是Queue.h中所有接口以及头文件引用的代码:

#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int QDataType;
typedef struct QueueNode {struct QueueNode* next;QDataType data;
}QNode;typedef struct Queue {QNode* head;QNode* tail;int size;
}Que;void QueueInit(Que* pq);
void QueueDestroy(Que* pq);
void QueuePush(Que*pq,QDataType x);
void QueuePop(Que* pq);
QDataType QueueFront(Que* pq);
QDataType QueueBack(Que* pq);
bool QueueEmpty(Que* pq);
int QueueSize(Que* p);
1.初始化队列:

把拿到的头指针和尾指针置空,然后把其值置为0...

void QueueInit(Que* pq) {assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}
2. 队尾入队列:

先使用malloc创建出一个队列,然后判断创建是否成功,如若成功执行下列代码,首先把指针置空然后给数据赋值,最后判断一下是第几个元素如果是第一个那么直接让头指针和尾指针都指向它即可,如果不是那么需要改变尾指针的指向,然后有效数据加加。

void QueuePush(Que* pq, QDataType x) {assert(pq);QNode* newnode = malloc(sizeof(QNode));if (newnode == NULL) {perror("malloc fail");exit(-1);}newnode->data = x;newnode->next = NULL;if (pq->tail==NULL) {pq->head = pq->tail = newnode;}else {pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}
3.队头出队列:

出数据大致原理就是保存第一个然后让头指针指向下一个然后再把之前那个释放了,最后有效数据个数减减即可。

void QueuePop(Que* pq) {assert(pq);assert(!QueueEmpty(pq));if (pq->head->next == NULL) {free(pq->head);pq->head = pq->tail = NULL;}else {QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}
4.获取队列头部元素:

队头有一个指针head直接拿取即可。

QDataType QueueFront(Que* pq) {assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}
 5.获取队列尾元素:

队尾有一个指针也就是tail直接拿取即可。

QDataType QueueBack(Que* pq) {assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}
6.获取队列中有效数据个数:

直接拿取有效数据size即可。

int QueueSize(Que* pq) {assert(pq);return pq->size;
}
7.检测队列是否为空,如果为空返回非零结果,如果非空返回0:

首先断言,返回时是一个表达式用来判断是否是真还是假。

bool QueueEmpty(Que* pq) {assert(pq);return pq->head == NULL;
}
8.销毁队列:

使用循环从队列的头部一直释放即可,最后把传进来的pq指针置空。

void QueueDestroy(Que* pq) {assert(pq);QNode* cur = pq->head;while (cur) {QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}

下列是队列接口实现的全部代码Queue.c中的:

#include"Queue.h"void QueueInit(Que* pq) {assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}void QueueDestroy(Que* pq) {assert(pq);QNode* cur = pq->head;while (cur) {QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}void QueuePush(Que* pq, QDataType x) {assert(pq);QNode* newnode = malloc(sizeof(QNode));if (newnode == NULL) {perror("malloc fail");exit(-1);}newnode->data = x;newnode->next = NULL;if (pq->tail==NULL) {pq->head = pq->tail = newnode;}else {pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}void QueuePop(Que* pq) {assert(pq);assert(!QueueEmpty(pq));if (pq->head->next == NULL) {free(pq->head);pq->head = pq->tail = NULL;}else {QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}
QDataType QueueFront(Que* pq) {assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}QDataType QueueBack(Que* pq) {assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}bool QueueEmpty(Que* pq) {assert(pq);return pq->head == NULL;
}
int QueueSize(Que* pq) {assert(pq);return pq->size;
}

然后test.c测试代码是否能够正常运行:

#include"Queue.h"void TestQueue() {Que q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);while (!QueueEmpty(&q)) {printf("%d ", QueueFront(&q));QueuePop(&q);}printf("\n");QueueDestroy(&q);
}int main() {TestQueue();
}

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

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

相关文章

谈谈SSH整合--一起学习吧之系统架构

SSH整合是一种非常实用的Web应用程序开发框架&#xff0c;能够大大提高开发效率和应用程序的质量。 一、定义 SSH整合是指将Spring、Hibernate和Struts2这三个框架进行集成&#xff0c;形成一个统一的Web应用程序开发框架。这种整合可以大大提高开发效率和应用程序的稳定性。…

【备忘录】docker-maven-plugin 使用

在使用docker-maven-plugin 插件时&#xff0c;经常会碰到一些奇怪的问题&#xff1a; 比如&#xff1a; 1、docker远程访问时&#xff0c;认证安全问题&#xff1f; 2、dockerHost 访问地址准确性&#xff1f; 3、需要多个tag时如何处理&#xff1f; 4、push 到仓库时&#xf…

Java代码示例:演示多态特性及子类方法重写(day17)

java代码里面体现多态的特点&#xff1a; 第一步创建一个父类father&#xff0c; 然后创建子类subclasses&#xff0c; 最后创建一个DemoMulti, 上面的父类特有的方法不是私有的&#xff0c;因此子类能够继承。 新建一个父类方法Father 创建子类subclasses 在下面的代码中…

LabVIEW深度学习

目录 一、配置环境1.1、显卡选择1.2、下载显卡驱动1.3、下载并安装Anaconda1.4、配置Anaconda软件包下载服务器1.5、配置虚拟环境tf_gpu1.6、安装vscode1.7、安装tensorflow1.8、下载安装Git1.9、安装TensorFlow Object Detection API框架1.10、安装依赖的python软件包1.11、配…

Python 简单使用 RabbitMQ

一、安装 pip install pika 二、推送消息到队列中 执行pythone方法 import pika import time# 用户名和密码 user_info pika.PlainCredentials(admin,admin)# 连接服务器上的rabbitMQ服务 connection pika.BlockingConnection(pika.ConnectionParameters(127.0.0.1, 5672,…

HTTPS、对称/非对称加密、SSL/TLS

问题描述&#xff1a;HTTP的请求和响应都是明文传输&#xff0c;有安全隐患 HTTPS&#xff1a;HTTPS并不是一个单独的协议&#xff0c;是在 TCP 和 HTTP 之间加入了 SSL/TLS 安全协议&#xff0c;使得报文能够加密传输&#xff0c;SSL是TLS的前身&#xff0c;现在使用的大多都…

Taro活动列表中,对某一个活动添加分享按钮

采用data-留下分享链接的拼接参数 1.在item文件中写按钮 openType“share” <ButtonclassName{classes.rowRightShareButton}openType"share"data-share-transfer-id{lastGiftingTransferId}data-share-picture-url{shareUrl}data-share-title{shareTitle}onClic…

【Node】使用Node.js构建简单的静态页面生成器

使用Node.js构建简单的静态页面生成器 在现代的Web开发中&#xff0c;静态网站因其速度快、安全性高而越来越受到开发者的青睐。本文将介绍如何使用Node.js构建一个简单的静态页面生成器&#xff0c;通过这个小项目&#xff0c;你将了解到静态网站生成的基本原理和实现方法。 …

在开源的基础上构建 AI 需要一种全新的应用程序安全方法

人工智能已经从科幻小说中涌现出来&#xff0c;进入了我们的日常生活。 在开源软件&#xff08;OSS&#xff09;模型的支持下&#xff0c;人工智能革命正在加速。这些模型是专为开发 AI 而制作的复杂开源代码包&#xff0c;使组织能够高效、大规模地部署 AI 模型。 虽然大多数…

LLM 的下一站 Mamba,取代 Transformer,虽然在争议

虽然业界大佬对Mamba有点争议&#xff0c;但是直觉而言&#xff0c;Mamba会取代 Transformer 成为LLM的基础模型算法。 1&#xff0c; Mamba 比 Transformer的优点 1.1 处理的序列更长 1.2 比Transformer 更快 1.3 可解释性、可理解性、可控性、可调试性比 Transformer 更强 2…

StreamingT2V文本生成视频多模态大模型,即将开源!

1、前言 Picsart人工智能研究所、德克萨斯大学和SHI实验室的研究人员联合推出了StreamingT2V视频模型。通过文本就能直接生成2分钟、1分钟等不同时间&#xff0c;动作一致、连贯、没有卡顿的高质量视频。 虽然StreamingT2V在视频质量、多元化等还无法与Sora媲美&#xff0c;但…

npm配置项管理

全局模块路径配置 修改配置项 在使用Windows系统时&#xff0c;C盘告急一直被大家所诟病的问题&#xff0c;而nodejs的包管理工具npm默认将全局模块路径设置到了C盘。现要将npm全局模块路径设置到其他位置&#xff0c;减小C盘压力 npm config set prefix "E:\nodejs\no…

【C++第二阶段】文件操作

以下内容仅为当前认识&#xff0c;可能有不足之处&#xff0c;欢迎讨论&#xff01; 文章目录 文件操作文件写入流程简单的demo写操作 文件读流程二进制写文件二进制读文件 文件操作 文件写入流程 写文件包括以下几个步骤 1.包含头文件 2.创建流对象 3.打开文件&#xff0…

大数据学习第十二天(hadoop概念)

1、服务器之间数据文件传递 1&#xff09;服务器之间传递数据&#xff0c;依赖ssh协议 2&#xff09;http协议是web网站之间的通讯协议&#xff0c;用户可已通过http网址访问到对应网站数据 3&#xff09;ssh协议是服务器之间&#xff0c;或windos和服务器之间传递的数据的协议…

IP SSL的应用与安装

IP SSL&#xff0c;即互联网协议安全套接字层&#xff0c;它是一种为网络通信提供安全及数据完整性的安全协议。在网络传输过程中&#xff0c;IP SSL可以对数据进行加密&#xff0c;这样即便数据在传输途中被截取&#xff0c;没有相应的解密密钥也无法解读内容。这一过程如同将…

合并两个单链表

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 但行前路&#xff0c;不负韶华&#…

redis的键值基本操作

设置数据 首先设置键值对 删除age&#xff0c;会得到nil&#xff0c;表示这个键已经被删除掉了 判断age键还在不在 查找所有键 查找所有以me结尾的键 删除所有键 redis的键和值都是二进制存储的&#xff0c;所以默认不支持中文。 但是&#xff0c;我们重新登录客户端&#xff…

Unity自定义框架(1)-----------单例模式

前言&#xff1a; Unity作为一款强大的游戏开发引擎&#xff0c;其基础框架的设计对于项目的结构和性能有着重要的影响。其中&#xff0c;单例模式是一种常用的设计模式&#xff0c;用于确保一个类只有一个实例&#xff0c;并提供一个全局访问点。 什么是单例模式&#xff1f…

基于深度学习的机场航拍小目标检测系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)

摘要&#xff1a;在本博客中介绍了基于YOLOv8/v7/v6/v5的机场航拍小目标检测系统。该系统的核心技术是采用YOLOv8&#xff0c;并整合了YOLOv7、YOLOv6、YOLOv5算法&#xff0c;从而进行性能指标的综合对比。我们详细介绍了国内外在机场航拍小目标检测领域的研究现状、数据集处理…

分布式唯一ID 雪花算法

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;算法分析与设计 ⛺️稳中求进&#xff0c;晒太阳 算法具体介绍 雪花算法是 64 位 的二进制&#xff0c;一共包含了四部分&#xff1a; 1位是符号位&#xff0c;也就是最高位&#xff0c;…