数据结构栈和堆列

目录

栈:

栈的概念:

栈的实现:

栈接口的实现:

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,一经查实,立即删除!

相关文章

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,…

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

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

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

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

【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;…

大数据实验一,Hadoop安装及使用

目录 一&#xff0e;实验内容 二&#xff0e;实验目的 三&#xff0e;实验过程截图及说明 1、安装SSH&#xff0c;并配置SSH无密码登录 2、配置java环境 3.Hadoop的安装与配置 4、修改四个配置文件&#xff1a; 5、格式化HDFS的NameNode&#xff1a; 6、启动Hadoop 7、…

如何使用极狐GitLab 启用自动备份功能

本文作者&#xff1a;徐晓伟 GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 本文主要讲述了如何极狐GitLab 自…

探索Flutter混淆在提高应用安全性方面的作用

在移动应用开发中&#xff0c;保护应用代码安全至关重要。Flutter 提供了简单易用的混淆工具&#xff0c;帮助开发者在构建 release 版本应用时有效保护代码。本文将介绍如何在 Flutter 应用中使用混淆&#xff0c;并提供了相关的操作步骤和注意事项。 &#x1f4dd; 摘要 本…

普通Java工程可执行JAR两种打包方式探讨

文章目录 一、需求概述二、代码结构三、运行结果四、打包设置1. 一体化可执行包2. 带外部依赖lib的可执行包 五、打包运行1. 源码放送2. 打包执行3. 打包结果 一、需求概述 普通Java工程 docker-show 实现了定时打印docker应用信息&#xff0c;现在需要将其打包成可执行Jar部署…

Nginx三大常用功能“反向代理,负载均衡,动静分离”

注意&#xff1a;以下案例在Windows系统计算机作为宿主机&#xff0c;Linux CentOS 作为虚拟机的环境中实现 一&#xff0c;Nginx配置实例-反向代理 1.反向代理 案例一 实现效果&#xff1a;使用nginx反向代理&#xff0c;访问 www.123.com 直接跳转到127.0.0.1:8080 准备工…

视频基础学习四——视频编码基础一(冗余信息)

文章目录 前言一、编码压缩的原理1.空间冗余帧内预测 2.时间冗余帧间预测运动估计运动补偿 3.编码冗余4.视觉冗余 二、压缩编码的流程1.编码器2.编解码流程 总结 前言 上一篇文章介绍了视频帧率、码率、与分辨率。也介绍了为什么需要对视频进行压缩&#xff0c;因为720P、rgb2…

计算机网络-HTTP相关知识-RSA和ECDHE及优化

HTTPS建立基本流程 客户端向服务器索要并验证服务器的公钥。通过密钥交换算法&#xff08;如RSA或ECDHE&#xff09;协商会话秘钥&#xff0c;这个过程被称为“握手”。双方采用会话秘钥进行加密通信。 RSA流程 RSA流程包括四次握手&#xff1a; 第一次握手&#xff1a;客户…