【数据结构】-- 栈和队列

🌈 个人主页:白子寰
🔥 分类专栏:python从入门到精通,魔法指针,进阶C++,C语言,C语言题集,C语言实现游戏👈 希望得到您的订阅和支持~
💡 坚持创作博文(平均质量分82+),分享更多关于深度学习、C/C++,python领域的优质内容!(希望得到您的关注~)

 

目录

引入

介绍

为什么栈用顺序表而不用数组? 

 栈的实现

stack.h:结构体,栈的声明与定义

stack.c:栈的具体实现代码

栈的初始化

压入

弹出 

取栈顶元素

栈的大小 

判断栈是否为空

栈的销毁

Test.c:栈的测试

队列

引入

介绍

为什么队列选择链表而不用数组? 

队列实现

Queue.h:结构体,队列的声明和定义

Queue.c:队列函数具体实现

队列初始化

队尾入队列(数据)

队头出队列(数据)

获取队列头部元素

获取队列尾部元素

判断队列是否为空

队列中有效元素个数

队列销毁

Test.c:队列的测试


引入


 

介绍

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

为什么栈用顺序表而不用数组? 

由于栈只用在同一端进行插入和删除,因此我们优先选择使用顺序表,因为在顺序表的末尾插入和删除的时间复杂度都是O(1),并且操作简单 


 

 栈的实现

stack.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 STTPop(ST* ps);
//栈的大小
int STSize(ST* ps);
//判断栈是否为空
bool STEmpty(ST* ps);

 

stack.c:栈的具体实现代码

栈的初始化
void STInit(ST* ps)
{assert(ps);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}
压入
void STPush(ST* ps, STDatatype x)
{assert(ps);//如果栈顶 = 容量,满了if (ps->top == ps->capacity){//扩容int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDatatype* tmp = (STDatatype*)realloc(ps->a, newcapacity * sizeof(STDatatype));if (tmp == NULL){perror("realloc");return;}//赋值ps->a = tmp;ps->capacity = newcapacity;}//新数据给值ps->a[ps->top] = x;ps->top++;
}
弹出 
void STPop(ST* ps)
{assert(ps);//判断栈是否为空assert(!STEmpty(ps));//栈顶元素删除ps->top--;
}
取栈顶元素
STDatatype STTPop(ST* ps)
{assert(ps);//判断栈是否为空assert(!STEmpty(ps));return ps->a[ps->top - 1];//栈顶元素下标
}
栈的大小 
int STSize(ST* ps)
{assert(ps);return ps->top;
}
判断栈是否为空
bool STEmpty(ST* ps)
{assert(ps);//为空返回True,不为空返回Falsereturn ps->top == 0;
}
栈的销毁
void STDestroy(ST* ps)
{//判断穿的指针是否有效assert(ps);//先释放,后置空free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}

 

Test.c:栈的测试

int main()
{ST st;//初始化STInit(&st);//压入STPush(&st, 1);//1STPush(&st, 2);//1 2 STPush(&st, 3);//1 2 3 STPush(&st, 4);//1 2 3 4//取栈顶元素int top = STTPop(&st);//4//printf("%d ", top);//4//弹出STPop(&st);//1 2 3//压入STPush(&st, 5);//1 2 3 5 STPush(&st, 6);//1 2 3 5 6while (!STEmpty(&st))//栈不为空{int top = STTPop(&st);//6 5 3 2 1printf("%d ", top);	  //6 5 3 2 1STPop(&st);}//摧毁STDestroy(&st);return 0;
}

 


队列

引入


 

介绍

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

为什么队列选择链表而不用数组? 

由于队列需要在队列两端进行插入或删除,因此我们优先选择链表来进行实现。当然使用数组实现也可以,只是数组在头部插入和删除元素需要O(n)时间复杂度,因此选择链表更优。 


 

队列实现

Queue.h:结构体,队列的声明和定义

#pragma once#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int QueDatatype;
typedef struct QueueNode
{int val;struct QueueNode* next;
}QNode;typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Que;//队列初始化
void QueueInit(Que* pq);
//队列销毁
void QueueDestroy(Que* pq);// 队尾入队列
void QueuePush(Que* pq, QueDatatype x);
// 队头出队列
void QueuePop(Que* pq);
//获取队列头部元素
QueDatatype QueueFront(Que* pq);
//获取队列尾部元素
QueDatatype QueueBack(Que* pq);
//判断队列中有效元素
bool QueueEmpty(Que* pq);
//队列中有效元素个数
int QueueSize(Que* pq);

 

Queue.c:队列函数具体实现

队列初始化
void QueueInit(Que* pq)
{assert(pq);//一开始队列为空pq->phead = NULL;pq->ptail = NULL;pq->size = 0;     //队列大小
}
队尾入队列(数据)
void QueuePush(Que* pq, QueDatatype x)
{assert(pq);//扩容QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc");return;}//给值newnode->val = x;newnode->next = NULL;//队列不止一个元素if (pq->ptail){pq->ptail->next = newnode;pq->ptail = newnode;}//队列只有一个元素else{pq->phead = pq->ptail = newnode;}pq->size++;
}
队头出队列(数据)
void QueuePop(Que* pq)
{assert(pq);assert(pq->phead);//队列中不止一个元素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--;
}
获取队列头部元素
QueDatatype QueueFront(Que* pq)
{assert(pq);//判断队列是否为空assert(pq->phead);return pq->phead->val;
}
获取队列尾部元素
QueDatatype QueueBack(Que* pq)
{assert(pq);//判断队列是否为空assert(pq->ptail);return pq->ptail->val;
}
判断队列是否为空
bool QueueEmpty(Que* pq)
{assert(pq);//为空返回True,不为空返回Falsereturn pq->size == 0;
}
队列中有效元素个数
int QueueSize(Que* pq)
{assert(pq);return pq->size;//队列大小
}
队列销毁
void QueueDestroy(Que* 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;
}

 

Test.c:队列的测试

#include"Queue.h"int main()
{Que q;//初始化QueueInit(&q);//队尾进入队列QueuePush(&q, 1);//1QueuePush(&q, 2);//1 2QueuePush(&q, 3);//1 2 3QueuePush(&q, 4);//1 2 3 4printf("%d ", QueueFront(&q));//1printf("%d ", QueueBack(&q));//4//对头出队列QueuePop(&q);//2 3 4printf("%d ", QueueFront(&q));//2printf("%d ", QueueBack(&q));//4printf("%d", QueueSize(&q));//3//while (!QueueEmpty(&q))//{//	printf("%d ", QueueFront(&q));//	QueuePop(&q);//}//销毁QueueDestroy(&q);return 0;
}

 

***********************************************************分割线*****************************************************************************
完结!!!
感谢浏览和阅读。

等等等等一下,分享最近喜欢的一句话:

“没有永恒的梅雨季,只有久违的艳阳天”。

我是白子寰,如果你喜欢我的作品,不妨你留个点赞+关注让我知道你曾来过。
你的点赞和关注是我持续写作的动力!!! 
好了划走吧。

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

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

相关文章

二十一.订单分析RFM模型

目录 1.数据读取 2.数据清洗 3.可视化分析 做图吧 4.RFM模型 本次数据条数为: 51101 import pandas as pd import numpy as np 1.数据读取 #读取文件 df_data pd.read_csv("../data/dataset.csv",encoding"gbk") df_data#因为列标签都是英文,这里我…

关于分布式session的问题

分布式session只能存储在当前的tomcat中&#xff0c;所以比如下次负载均衡到其他服务器会出现问题 session同步&#xff0c;在一个session中存储后同步到其他的服务器&#xff08;耗时&#xff0c;影响性能&#xff09;信息不存在session中了&#xff0c;存cooking中&#xff0…

通讯录的实现(顺序表)

前言&#xff1a;上篇文章我们讲解的顺序表以及顺序表的具体实现过程&#xff0c;那么我们的顺序表在实际应用中又有什么作用呢&#xff1f;今天我们就基于顺序表来实现一下通讯录。 目录 一.准备工作 二.通讯录的实现 1.通讯录的初始化 2.插入联系人 3.删除联系人 4.…

LeetCode 454.四数相加II

LeetCode 454.四数相加II 1、题目 题目链接&#xff1a;454. 四数相加 II - 力扣&#xff08;LeetCode&#xff09; 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a; 0 <…

手机副业赚钱秘籍:让你的手机变成赚钱利器

当今社会&#xff0c;智能手机已然成为我们生活不可或缺的一部分。随着技术的飞速进步&#xff0c;手机不再仅仅是通讯工具&#xff0c;而是化身为生活伴侣与工作助手。在这个信息爆炸的时代&#xff0c;我们时常会被一种焦虑感所困扰&#xff1a;如何能让手机超越消磨时光的定…

TinyEMU源码分析之访存处理

TinyEMU源码分析之访存处理 1 访存指令介绍2 指令译码3 地址转换3.1 VA与PA3.2 VA转PA 4 判断地址空间范围5 执行访存操作5.1 访问RAM内存5.2 访问非RAM&#xff08;设备&#xff09;内存 6 访存处理流程图 本文属于《 TinyEMU模拟器基础系列教程》之一&#xff0c;欢迎查看其…

【AI】什么是Ai Agent

什么是AI Agent&#xff1f; AI Agent是指人工智能代理&#xff08;Artificial Intelligence Agent&#xff09;是一种能够感知环境进行自主理解&#xff0c;进行决策和执行动作的智能体。AI Agent具备通过独立思考、调用工具逐步完成给定目标的能力。不同于大模型的区别在于&…

OpenHarmony实战开发-如何使用屏幕属性getDefaultDisplaySync、getCutoutInfo接口实现适配挖孔屏。

介绍 本示例介绍使用屏幕属性getDefaultDisplaySync、getCutoutInfo接口实现适配挖孔屏。该场景多用于沉浸式场景下。 效果图预览 使用说明 1.加载完成后顶部状态栏时间和电量显示位置规避了不可用区域。 实现思路 1.通过setWindowLayoutFullScreen、setWindowSystemBarEn…

代码随想录训练营

Day23代码随想录 669.修剪二叉搜索树 1.题目描述 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即&#xff0c;如果没有…

k8s 节点打污点

例如&#xff0c;给节点node-1打上一个名为special值为true&#xff0c;效果为NoSchedule的污点&#xff0c;命令如下&#xff1a; kubectl taint nodes node-1 specialtrue:NoSchedule 污点格式为“KeyValue:Effect”&#xff0c;Key和Value作为污点的标签&#xff0c;Value…

Hbase的简单学习一

一 Hbase的搭建与安装 1.1 安装 1.准备好文件&#xff0c;上传到Linux上 2.解压文件 tar zxvf hbase-2.2.7-bin.tar.gz -C ../ ../是解压到的路径 1.2 配置文件 1.配置环境变量 去etc/profile目录下 export HBASE_HOME/usr/local/soft/hbase-2.2.7 export PATH$PATH:$H…

-存储器-

1存储器简介 存储器是一种保存数据的硬件单元2存储器分类 2.1按照数据易失性 2.1.1易失性存储器【RAM-Random Access Memory】 2.1.1.1【SRAM-Static Random Access Memory】 用晶体管存储0、1。速度快&#xff0c;成本高&#xff0c;存储密度低。2.1.1.2【DRAM-Dynamic R…

.NET SignalR Redis实时Web应用

环境 Win10 VS2022 .NET8 Docker Redis 前言 什么是 SignalR&#xff1f; ASP.NET Core SignalR 是一个开放源代码库&#xff0c;可用于简化向应用添加实时 Web 功能。 实时 Web 功能使服务器端代码能够将内容推送到客户端。 适合 SignalR 的候选项&#xff1a; 需要从服…

GCDAsynSocket之TCP简析

GCDAsynSocket是一个开源的基于GCD的异步的socket库。它支持IPV4和IPV6地址&#xff0c;TLS/SSL协议。同时它支持iOS端和Mac端。本篇主要介绍一下GCDAsynSocket中的TCP用法和实现。 首先通过下面这个方法初始化一个GCDAsynSocket对象。 - (id)initWithDelegate:(id<GCDAsyn…

AI预测福彩3D第38弹【2024年4月17日预测--第8套算法开始计算第6次测试】

今天咱们继续测试第8套算法和模型&#xff0c;今天是第5次测试&#xff0c;目前的测试只是为了记录和验证&#xff0c;为后续的模型修改和参数调整做铺垫&#xff0c;所以暂时不建议大家盲目跟买~废话不多说了&#xff0c;直接上结果&#xff01; 2024年4月17日3D的七码预测结果…

Python中常见错误汇总(持续更新中)

Python中常见错误汇总&#xff08;持续更新中&#xff09; Problem1 ModuleNotFoundError: No module named sklearn.datasets.samples_generator’Problem2 ‘sklearn.externals’ (C:\anaconda\lib\site-packages\sklearn\externals_*init*_.pyProblem3 AttributeError: modu…

K8S node节点执行kubectl get pods报错

第一个问题是由第二个问题产生的&#xff0c;第二个问题也是最常见的 网上找的都是从master节点把文件复制过来&#xff0c;这样确实可以解决&#xff0c;但是麻烦&#xff0c;有一个node节点还好&#xff0c;如果有多个呢&#xff1f;每个都复制吗&#xff1f;下面是我从外网…

Jackson 2.x 系列【20】混合注解 Mixin Annotations

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Jackson 版本 2.17.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 1. 需求场景2. 混合注解2.1 创建混合类2.2 关联2.3 测试 3. JsonMixin 1. 需求场…

RabbitMQ-核心特性

已经不需要为RabbitMQ交换机的离去而感到伤心了&#xff0c;接下来登场的是RabbitMQ-核心特性!!! 文章目录 核心特性消息过期机制消息确认机制死信队列 核心特性 消息过期机制 官方文档&#xff1a;https://www.rabbitmq.com/ttl.html 可以给每条消息指定一个有效期&#xf…

Ubuntu 20.04.06 PCL C++学习记录(二十五)

[TOC]PCL中点云分割模块的学习 学习背景 参考书籍&#xff1a;《点云库PCL从入门到精通》以及官方代码PCL官方代码链接,&#xff0c;PCL版本为1.10.0&#xff0c;CMake版本为3.16&#xff0c;可用点云下载地址 学习内容 使用渐进形态滤波器分割识别地面回波&#xff0c;即执…