纯c实现栈和队列 数据结构大全
栈
栈是一种后进先出的数据结构,可以用数组来模拟实现,掌握必要的数据结构是非常的有必要的
一样是先打出头文件
#pragma once#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>typedef int type;
typedef struct stack
{type* a;int top;//栈顶int capa;
}st;void stinit(st* pst);// 初始化
void stdestroy(st* pst);
void stpush(st* pst, type x);// 入
void stpop(st* pst);// 出
type sttop(st* pst);// 获取栈顶数据
bool stempty(st* pst);
int stsize(st* pst);
因为栈的特性,栈对比链表简单了不少
接下来我们来实现它的功能接口
初始化
使用typedef int是因为我们可能要存其他类型的数据,这样我们可以很容易的改变存进来的数据类型,避免麻烦的替换操作
栈也分数组栈和链式栈,但我们很容易发现既然是后进先出,那么数组栈会更简单,更合理
typedef int type;
typedef struct stack
{type* a;int top;//栈顶int capa;
}st;
//数组栈 和 链式栈
//后进先出
#include "stack.h"void stinit(st* pst)// 初始化
{assert(pst);//经典判空pst->a = NULL;pst->top = 0;//指向栈顶数据pst->capa = 0;
}
销毁空间
void stdestroy(st* pst)
{assert(pst);free(pst->a);pst->a = NULL;pst->top = pst->capa = 0;
}
必要的接口,避免内存泄漏
因为是数组实现,所以直接对a这块空间释放就可以了
入栈
void stpush(st* pst, type x)// 入栈
{if (pst->top == pst->capa){type newcapa = pst->capa == 0 ? 4 : pst->capa * 2;type* tmp = (type*)realloc(pst->a, newcapa * sizeof(type));if (tmp == NULL){perror("realloc fail\n");return;}pst->a = tmp;pst->capa = newcapa;}pst->a[pst->top++] = x;
}
第一个if是检查栈是否为0需要开辟空间,或者是栈是不是已经满了要开辟空间
要是if条件里面判断为真,我们就需要用两倍开辟新的空间
开辟完后再把数据入栈,同时记得更新a的地址以及容量capa的大小
出栈
void stpop(st* pst)// 出栈
{assert(pst);assert(!stempty(pst));//不为空才可以删pst->top--;
}
出栈很简单,判空之后直接top--,跟顺序表的尾删一样
获取栈顶数据
type sttop(st* pst)// 获取栈顶数据
{assert(pst);assert(!stempty(pst));//不为空才可以访问return pst->a[pst->top - 1];//避免越界访问
}
一样判空之后直接return top的值就可以提取出来了
判空
bool stempty(st* pst)
{assert(pst);return pst->top == 0;
}
检查top的值即可
检查数量
int stsize(st* pst)
{assert(pst);return pst->top;
}
一样检查top的值即可
测试
下面是测试代码,大家可以自己修改测试栈的功能
void stacktest1()//测试栈功能
{st s;//使用栈结构初始化stinit(&s);stpush(&s, 1);stpush(&s, 3);stpush(&s, 4);stpush(&s, 2);stpush(&s, 1);sttop(&s);stpop(&s);sttop(&s);while (!stempty(&s))//遍历 但是遍历一遍栈的数据就没了{printf("%d ", sttop(&s));stpop(&s);}stdestroy(&s);
}
int main()
{stacktest1();return 0;
}
队列
队列是一种先进先出的数据结构,可以用链表来模拟实现,掌握必要的数据结构是非常的有必要的
因为是先进先出的特性,数组来模拟头删会特别慢
还是照例给出头文件
/一个是结点,好去malloc,一个是整体,整体是为了方便,提高效率
typedef struct quenenode
{struct quenenode* next;type data;
}qnode;typedef struct quene
{qnode* phead;qnode* ptail;int size;
}queue;
//void queueinit(queue* pq);
void queuedestroy(queue* pq);
void queuepush(queue* pq,type x);
void queuepop(queue* pq);
type queuefront(queue* pq);//取头
type queueback(queue* pq);//取尾
int queuesize(queue* pq);
bool queueempty(queue* pq);
和前面的数据结构不同的是,队列创建了两个结构体来提高接口的效率
初始化
接口调用的都是queue结构体,另一个结构体仅存数据和操作来指向next
//队列
//链式队列
//先进先出
//尾进头出#include "quene.h"void queueinit(queue* pq)//总体的初始化
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
销毁空间
void queuedestroy(queue* pq)
{assert(pq);qnode* cur = pq->phead;//遍历指针while (cur){qnode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}
因为队列是链表为基础的,所以我们要创建一个结点来专门遍历销毁
最后再将phead和ptail置为空指针,size置为0
入队列
void queuepush(queue* pq, type x)
{assert(pq);qnode* newnode = (qnode*)malloc(sizeof(qnode));if (newnode == NULL){perror("malloc fail\n");return;}newnode->data = x;newnode->next = NULL;if (pq->ptail == NULL){assert(pq->phead == NULL);pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;//存数据进结点pq->ptail = newnode;//更新尾指针}pq->size++;
}
最开始还是经典判空,然后建立一个结点来接受新开辟的空间,然后将数据存入新建立的节点中,然后更新原本最后的结点的next的值,最后再将ptail指向新建立的结点,然后将描述数量的size++
出队列
void queuepop(queue* pq)//对头出数据
{assert(pq);assert(!queueempty(pq));if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}else{//头删qnode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}
首先判空,因为空的话会出现未定义行为
然后判断只有一个结点的情况,因为只有一个结点的时候next指向NULL
然后出队列其实就是头删,先建立一个结点保存头数据的next,然后将phead释放,再将phead指向新建立的next处
取头取尾
type queuefront(queue* pq)//取头
{assert(pq);assert(!queueempty(pq));return pq->phead->data;
}
type queueback(queue* pq)//取尾
{assert(pq);assert(!queueempty(pq));return pq->ptail->data;
}
很简单直接取出phead 和 ptail 但是标准官方版的队列有这个接口,所以我们也实现一下
检查数量
int queuesize(queue* pq)//数量
{assert(pq);return pq->size;
}
跟上面的取头取尾一样,官方版的队列有这个接口,我们直接返回size即可
判空
bool queueempty(queue* pq)//判断空
{assert(pq);return pq->phead == NULL;//判断ptail跟size都可以
}
判空有很多种写法,自习挑选一种即可
测试
下面是测试代码,大家可以自己修改测试队列的功能
void testqueue()
{queue q;queueinit(&q);queuepush(&q, 1);queuepush(&q, 3);queuepush(&q, 2);queuepush(&q, 4);queuefront(&q);queueback(&q);while (!queueempty(&q)){printf("%d ", queuefront(&q));queuepop(&q);}printf("\n");queuedestroy(&q);
}int main()
{testqueue();return 0;
}
相关文章:
纯c实现栈和队列 数据结构大全
栈 栈是一种后进先出的数据结构,可以用数组来模拟实现,掌握必要的数据结构是非常的有必要的 一样是先打出头文件 #pragma once#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include &…...
测试开发基础 | 计算机网络篇(二):物理层与数据链路层
【摘要】 计算机网络知识是自动化测试等技术基础,也是测试面试必考题目。霍格沃兹测试学院特别策划了本系列文章,将带大家一步步夯实计算机网络的基础知识。由于物理层知识在互联网软件研发工作中用到的并不多,所以可以仅做一个简单的了解。物…...
【深度学习】BasicSR训练过程记录,如何使用BasicSR训练GAN
文章目录 两种灵活的使用场景项目结构概览简化的使用方式 项目结构解读1. 代码的入口和训练的准备工作2. data和model的创建2.1 dataloader创建2.2 model的创建 3. 训练过程 动态实例化的历史演进1. If-else判断2. 动态实例化3. REGISTER注册机制 REGISTER注册机制的实现1. DAT…...
喜讯 | 华院计算摘得“2023大数据产业年度创新技术突破”奖
2024年1月17日, 由数据猿和上海大数据联盟主办,上海市经济和信息化委员会、上海市科学技术委员会指导的“第六届金猿季&魔方论坛——大数据产业发展论坛”在上海市四行仓库举行。论坛以“小趋势大未来”为主题,围绕大数据产业的各个领域展…...
stm32高级定时器死区时间
为什么要有死区时间 高级控制定时器(TIM1和TIM8)能够输出两路互补信号,并且能够管理输出的瞬时关断和接通。这段时间通常被称为死区,用户应该根据连接的输出器件和它们的特性(电平转换的延时、电源开关的延时等)来调整死区时间。 死区发生器 在生成的参…...
Python项目——久坐提醒定时器(PySide6)编写
1、介绍 使用Python编写一个久坐提醒软件。功能: 设置工作时间。设置休息时间。选择休息时是否播放音乐。休息时,软件置顶,且不能关闭。 2、工具 语言:python3.11UI设计工具:Qt designer编译器:PyCharm包…...
Linux,常见的强制退出/结束命令(ctr+c/ctr+d/:q/exit)
PS: 一直搞不清楚,这四个命令区别,干脆每个都输入一遍,逮着哪个算哪个。 1. CtrlC用途: 中断正在运行的程序或命令。(例如输入Ping命令一直处于等待状态,就像是进程一直等待干脆杀死࿰…...
检查一个Java List是否包含某个JavaBean对象的特定值,并且获取这个值
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { // 创建一个新的ArrayList List<MyBean> list new ArrayList<MyBean>(); // 添加一些元素 list.add(new MyBean("apple", …...
浮点数详解
目录 1.概述 2.浮点数的编码方式 2.1.float类型的IEEE编码 2.2.double类型的IEEE编码 2.3.现场问题 2.4.总结 1.概述 计算机也需要运算和存储数学中的实数。在计算机的发展过程中,曾产生过多种存储实数的方式,有的现在已经很少使用了。不管如何存储…...
LED流水灯
这段代码是用于STM32F10x系列微控制器的程序,主要目的是初始化GPIOA并使其所有引脚按照特定的模式进行闪烁。下面是对这段代码的逐行解释: #include "stm32f10x.h":这一行包含了STM32F10x系列微控制器的设备头文件。这个头文件包含…...
MySQL-B-tree和B+tree区别
B-tree(平衡树)和Btree(平衡树的一种变种)是两种常见的树状数据结构,用于构建索引以提高数据库的查询性能。它们在一些方面有相似之处,但也有一些关键的区别。以下是B-tree和Btree的主要区别: …...
架构篇08:架构设计三原则
文章目录 合适原则简单原则演化原则小结 成为架构师是每个程序员的梦想,但并不意味着把编程做好就能够自然而然地成为一个架构师,优秀程序员和架构师之间还有一个明显的鸿沟需要跨越,这个鸿沟就是“不确定性”。 对于编程来说,本…...
基于SpringBoot Vue汽车租赁系统
大家好✌!我是Dwzun。很高兴你能来阅读我,我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结,还为大家分享优质的实战项目,本人在Java项目开发领域有多年的经验,陆续会更新更多优质的Java实战项目&#x…...
idea带的maven在SpringBoot下载jar包出错、下载jar包速度慢
找到idea安装目录 /IntelliJ IDEA/plugins/maven/lib/maven3/conf/settings.xml 搜索:mirrors 添加到mirrors标签里。(默认下载包是从国外拉取,速度慢,现在替换成国内阿里的链接) <mirror><id>central</id><…...
datasets的一些使用技巧
#加载某类文件作为数据集 dataset load_dataset("json", data_files"./train_pair_1w.json", split"train") #加载数据集中的子数据集 datasets load_dataset("clue",name"afqmc",#trust_remote_codeTrue) train_datas…...
react 实现页面状态缓存(keep-alive)
前言: 因为 react、vue都是单页面应用,路由跳转时,就会销毁上一个页面的组件。但是有些项目不想被销毁,想保存状态。 比如:h5项目跳转其他页面返回时,页面状态不丢失。设想一个 页面我滑倒了中间…...
spring和springboot、springMVC有什么区别?
前言 大家好,我是chowley,今天来聊一下,刚在面试中被问到的一个经典问题 spring和springboot、springMVC有什么区别? Spring、Spring Boot 和 Spring MVC 是 Spring Framework 生态中的不同组件,各自有不同的角色和…...
centos 启动nacos pg版本
背景:支持国产化需求,不再使用mysql 1.修改插件 git clone https://github.com/wuchubuzai2018/nacos-datasource-extend-plugins.git cd nacos-datasource-extend-plugins/nacos-postgresql-datasource-plugin-ext mvn package编译成功后,…...
实验:MySQL 客户端SocketTimeout 抓包分析
实验准备 服务端环境准备 服务器信息 阿里云 99 大洋白嫖机 $ cat /proc/version Linux version 5.15.0-83-generic (builddlcy02-amd64-027) (gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #92-Ubuntu SMP Mon Aug 14 09:30:42 UT…...
rocketmq双主双从部署+dashbord
1、主机规划 主机节点地址主机Anamesrv192.168.2.228:9876主机Abroker-a192.168.2.228:10911主机Abroker-b192.168.2.228:11911主机Bnamesrv192.168.2.229:9876主机Bbroker-c192.168.2.229:10911主机Bbroker-d192.168.2.229:11911 2、两台主机都需要执行,创建mq需…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
如何在Windows本机安装Python并确保与Python.NET兼容
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
【Zephyr 系列 16】构建 BLE + LoRa 协同通信系统:网关转发与混合调度实战
🧠关键词:Zephyr、BLE、LoRa、混合通信、事件驱动、网关中继、低功耗调度 📌面向读者:希望将 BLE 和 LoRa 结合应用于资产追踪、环境监测、远程数据采集等场景的开发者 📊篇幅预计:5300+ 字 🧭 背景与需求 在许多 IoT 项目中,单一通信方式往往难以兼顾近场数据采集…...
ubuntu清理垃圾
windows和ubuntu 双系统,ubuntu 150GB,开发用,基本不装太多软件。但是磁盘基本用完。 1、查看home目录 sudo du -h -d 1 $HOME | grep -v K 上面的命令查看$HOME一级目录大小,发现 .cache 有26GB,.local 有几个GB&am…...
基于微信小程序的作业管理系统源码数据库文档
作业管理系统 摘 要 随着社会的发展,社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景,运用软件工程原理和开发方法,它主要是采用java语言技术和微信小程序来完成对系统的…...
CSP信奥赛C++常用系统函数汇总
# CSP信奥赛C常用系统函数汇总## 一、输入输出函数### 1. cin / cout(<iostream>) cpp int x; cin >> x; // 输入 cout << x << endl;// 输出 优化:ios::sync_with_stdio(false); 可提升速度 2. scanf() /…...
