数据结构:详解【栈和队列】的实现

目录

  • 1. 栈
    • 1.1 栈的概念及结构
    • 1.2 栈的实现
    • 1.3 栈的功能
    • 1.4 栈的功能的实现
    • 1.5 完整代码
  • 2. 队列
    • 2.1 队列的概念及结构
    • 2.2 队列的实现
    • 2.3 队列的功能
    • 2.4 队列的功能的实现
    • 2.5 完整代码

1. 栈

1.1 栈的概念及结构

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

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

在这里插入图片描述
在这里插入图片描述

1.2 栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾插和头删的实际复杂度为O(1),是非常合适的。

在这里插入图片描述

1.3 栈的功能

  • 初始化栈
  • 销毁栈
  • 入栈
  • 出栈
  • 获取栈顶元素
  • 获取栈内有效元素的个数
  • 判断栈内是否为空,如果为空返回非0结果,不为空返回0

1.4 栈的功能的实现

(1)定义一个动态增长的栈

typedef int STDataType;typedef struct Stack
{STDataType* a;STDataType top;//定义栈顶size_t capacity;//栈的容量
}ST;

(2)初始化栈

void StackInit(ST* ps)
{//初始化空间ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);if (ps->a == NULL){printf("malloc fail!\n");return;}ps->top = 0;ps->capacity = 4;//初始化4个空间
}

(3)销毁栈

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

(4)入栈(相当于顺序表的尾插)

void StackPush(ST* ps, STDataType x)
{//插入数据之前判断是否增容if (ps->top == ps->capacity){STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * sizeof(STDataType) * 2);if (tmp == NULL){printf("realloc fail!\n");return;}else{ps->a = tmp;ps->capacity *= 2;}}ps->a[ps->top] = x;ps->top++;
}

(5)出栈(相当于顺序表的头删)

void StackPop(ST* ps)
{assert(ps);//断言,栈内为空则终止程序ps->top--;
}

(6)获取栈顶元素

STDataType StackTop(ST* ps)
{assert(ps);//断言,栈内为空则终止程序assert(ps->top > 0);return ps->a[ps->top - 1];
}

(7)获取栈内有效元素的个数

int StackSize(ST* ps)
{assert(ps);return ps->top;
}

(8)判断栈内是否为空,如果为空返回非0结果,不为空返回0

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

1.5 完整代码

Stack.h

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int STDataType;typedef struct Stack
{STDataType* a;STDataType top;//定义栈顶size_t capacity;//栈的容量
}ST;//初始化栈
void StackInit(ST* ps);//销毁栈
void StackDestory(ST* ps);//从栈顶插入数据
void StackPush(ST* ps, STDataType x);//从栈顶删除数据
void StackPop(ST* ps);//获取栈顶元素
STDataType StackTop(ST* ps);//获取栈内有效元素个数
int StackSize(ST* ps);//判断栈内是否为空,如果为空返回非0结果,不为空返回0
bool StackEmpty(ST* ps);

Stack.c

#define _CRT_SECURE_NO_WARNINGS #include "Stack.h"void StackInit(ST* ps)
{//初始化空间ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);if (ps->a == NULL){printf("malloc fail!\n");return;}ps->top = 0;ps->capacity = 4;//初始化4个空间
}void StackDestory(ST* ps)
{free(ps->a);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}void StackPush(ST* ps, STDataType x)
{//插入数据之前判断是否增容if (ps->top == ps->capacity){STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * sizeof(STDataType) * 2);if (tmp == NULL){printf("realloc fail!\n");return;}else{ps->a = tmp;ps->capacity *= 2;}}ps->a[ps->top] = x;ps->top++;
}void StackPop(ST* ps)
{assert(ps);//断言,栈内为空则终止程序ps->top--;
}STDataType StackTop(ST* ps)
{assert(ps);//断言,栈内为空则终止程序assert(ps->top > 0);return ps->a[ps->top - 1];
}int StackSize(ST* ps)
{assert(ps);return ps->top;
}bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

Test.c

#define _CRT_SECURE_NO_WARNINGS #include "Stack.h"void StackTest()
{ST st;StackInit(&st);StackPush(&st, 1);StackPush(&st, 2);StackPush(&st, 3);StackPush(&st, 4);//打印栈内的数据,由于不能破坏栈的特性,所以不能遍历while (!StackEmpty(&st)){printf("%d ", StackTop(&st));StackPop(&st);}StackDestory(&st);
}int main()
{StackTest();return 0;
}

2. 队列

2.1 队列的概念及结构

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

2.2 队列的实现

队列也可以数组和链表的结构实现,使用单链表的结构实现更优一些。
因为如果使用数组的结构,出队列在数组头上出数据,这时需要挪动数据,时间复杂度为O(n),效率会比较低。
而单链表的尾插和头删的时间复杂度为O(1),十分合适。
在这里插入图片描述

2.3 队列的功能

  • 初始化队列
  • 销毁队列
  • 入队列
  • 出队列
  • 获取队列头部元素
  • 获取队列尾部元素
  • 获取队列中有效元素的个数
  • 判断队列是否为空,为空返回非0,不为空返回0

2.4 队列的功能的实现

(1)定义一个队列

typedef int QTDataType;typedef struct QNode
{struct QNode* next;QTDataType data;
}QNode;typedef struct Queue
{struct QNode* tail;struct QNode* head;
}Queue;

(2)初始化队列

void QueueInit(Queue* pq)
{assert(pq);pq->head = pq->tail = NULL;
}

(3)销毁队列

void QueueDestory(Queue* pq)
{assert(pq);QNode* cur = pq->head;while (cur){cur = cur->next;free(cur);}pq->head = pq->tail = NULL;
}

(4)入队列(相当于单链表的尾插)

void QueuePush(Queue* pq, QTDataType x)
{assert(pq);QNode* newnode = (QTDataType*)malloc(sizeof(QTDataType));if (newnode == NULL){printf("malloc fail!\n");return;}newnode->data = x;newnode->next = NULL;//第一个结点if (pq->tail == NULL){pq->head = pq->tail = newnode;}//多个节点else{pq->tail->next = newnode;pq->tail = newnode;}}

(5)出队列(相当于单链表的头删)

void QueuePop(Queue* pq)
{assert(pq);assert(pq->head);//只有一个节点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;}
}

(6)获取队列头部元素

QTDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->head);return pq->head->data;
}

(7)获取队列尾部元素

QTDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->head);return pq->tail->data;
}

(8)获取队列中有效元素的个数

int QueueSize(Queue* pq)
{assert(pq);int size = 0;QNode* cur = pq->head;while (cur){size++;cur = cur->next;}return size;
}

(9)判断队列是否为空,为空返回非0,不为空返回0

int QueueEmpty(Queue* pq)
{assert(pq);return pq->head == NULL;
}

2.5 完整代码

Queue.h

#pragma once#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int QTDataType;typedef struct QNode
{struct QNode* next;QTDataType data;
}QNode;typedef struct Queue
{struct QNode* tail;struct QNode* head;
}Queue;//初始化队列
void QueueInit(Queue* pq);//销毁队列
void QueueDestory(Queue* pq);//队尾入队列
void QueuePush(Queue* pq, QTDataType x);//队头出队列
void QueuePop(Queue* pq);//获取队列头部元素
QTDataType QueueFront(Queue* pq);//获取队列尾部元素
QTDataType QueueBack(Queue* pq);//判断队列是否为空,为空返回非0,不为空返回0
int QueueEmpty(Queue* pq);//获取队列中有效元素的个数
int QueueSize(Queue* pq);

Queue.c

#define _CRT_SECURE_NO_WARNINGS #include "Queue.h"void QueueInit(Queue* pq)
{assert(pq);pq->head = pq->tail = NULL;
}void QueueDestory(Queue* pq)
{assert(pq);QNode* cur = pq->head;while (cur){cur = cur->next;free(cur);}pq->head = pq->tail = NULL;
}void QueuePush(Queue* pq, QTDataType x)
{assert(pq);QNode* newnode = (QTDataType*)malloc(sizeof(QTDataType));if (newnode == NULL){printf("malloc fail!\n");return;}newnode->data = x;newnode->next = NULL;//第一个结点if (pq->tail == NULL){pq->head = pq->tail = newnode;}//多个节点else{pq->tail->next = newnode;pq->tail = newnode;}}void QueuePop(Queue* pq)
{assert(pq);assert(pq->head);//只有一个节点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;}
}int QueueEmpty(Queue* pq)
{assert(pq);return pq->head == NULL;
}QTDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->head);return pq->head->data;
}QTDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->head);return pq->tail->data;
}int QueueSize(Queue* pq)
{assert(pq);int size = 0;QNode* cur = pq->head;while (cur){size++;cur = cur->next;}return size;
}

Test.c

#define _CRT_SECURE_NO_WARNINGS #include "Queue.h"void QueueTest()
{Queue q;QueueInit(&q);QueuePush(&st, 1);QueuePush(&st, 2);QueuePush(&st, 3);QueuePush(&st, 4);//打印队列内的数据,由于不能破坏队列的特性,所以不能遍历while (!QueueEmpty(&st)){printf("%d ", QueueFront(&st));QueuePop(&st);}QueueDestory(&q);}int main()
{QueueTest();return 0;
}

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

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

相关文章

模拟B\S服务器(扩展知识点)

3.2 模拟B\S服务器(扩展知识点) 模拟网站服务器&#xff0c;使用浏览器访问自己编写的服务端程序&#xff0c;查看网页效果。 案例分析 准备页面数据&#xff0c;web文件夹。 复制到我们Module中&#xff0c;比如复制到day08中 我们模拟服务器端&#xff0c;ServerSocket类…

SpringCloud Alibaba实战和源码(8)OpenFeign使用

1、 使用Feign实现远程HTTP调用 1.1、常见HTTP客户端 HttpClient HttpClient 是 Apache Jakarta Common 下的子项目&#xff0c;用来提供高效的、最新的、功能丰富的支持 Http 协 议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议最新版本和建议。HttpClient 相比传统 J…

RN开发搬砖经验之—处理“Duplicate class com.github.barteksc.pdfviewer“

问题信息 Duplicate class com.github.barteksc.pdfviewer.PDFView found in modules jetified-AndroidPdfViewer-3.1.0-beta.3-runtime (com.github.TalbotGooday:AndroidPdfViewer:3.1.0-beta.3) and jetified-android-pdf-viewer-2.8.2-runtime (com.github.barteksc:andro…

为车主提供多路况安全保障!“北欧轮胎安全专家”熊牌轮胎迎来全新升级

德国马牌轮胎旗下明星品牌——Gislaved熊牌轮胎迎来全新升级。 自进入中国市场以来&#xff0c;熊牌轮胎凭借着坚韧安全、静音降噪等特点&#xff0c;收获无数好评。此次全新升级的熊牌轮胎&#xff0c;在品牌logo中加入了“北欧棕熊”的形象&#xff0c;并且对此前轮胎标签中的…

qt使用Windows经典风格,以使QTreeView或QTreeWidge有节点线或加号

没有使用Windows经典风格的QTreeView或QTreeWidget显示如下&#xff1a; 使用Windows经典风格的QTreeView或QTreeWidget显示如下&#xff1a; 树展开时&#xff1a; 树未展开时&#xff1a; 可以看到&#xff1a; 未使用Windows经典风格时&#xff0c;QTreeView或QTreeWidget…

【MySQL】基本查询(1)

【MySQL】基本查询&#xff08;1&#xff09; 目录 【MySQL】基本查询&#xff08;1&#xff09;表的增删改查Create单行数据 全列插入多行数据 指定列插入插入否则更新替换 RetrieveSELECT 列全列查询指定列查询查询字段为表达式为查询结果指定别名结果去重 WHERE 条件英语不…

第六篇:视频广告格式上传指南(上) - IAB视频广告标准《数字视频和有线电视广告格式指南》

第六篇&#xff1a; 视频广告格式和上传指南&#xff08;上&#xff09; --- 我为什么要翻译介绍美国人工智能科技公司IAB系列技术标准&#xff08;2&#xff09; 流媒体数字视频的广告格式分为线性和非线性两大类。任何一个广告都可以与显示在视频播放器外部的伴随横幅一起提…

【Linux文件系列】重定向

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

CMake学习(下)

1. 嵌套的CMake 如果项目很大&#xff0c;或者项目中有很多的源码目录&#xff0c;在通过CMake管理项目的时候如果只使用一个CMakeLists.txt&#xff0c;那么这个文件相对会比较复杂&#xff0c;有一种化繁为简的方式就是给每个源码目录都添加一个CMakeLists.txt文件&#xff…

windows系统下python进程管理系统

两年来&#xff0c;我们项目的爬虫代码大部分都是放在公司的windows机器上运行的&#xff0c;原因是服务器太贵&#xff0c;没有那么多资源&#xff0c;而windows主机却有很多用不上。为了合理利用公司资源&#xff0c;降低数据采集成本&#xff0c;我在所以任务机器上使用anac…

将本地的项目上传到gitee,

场景&#xff1a;在本地有一个项目&#xff0c;想要把这个项目上传到gitee&#xff0c;且在gitee中已经创建好仓库 依次执行下图中的命令&#xff1a;

【linux】进程地址空间(进程三)

目录 快速了解&#xff1a;引入最基本的理解&#xff1a;细节&#xff1a;如何理解地址空间&#xff1a;a.什么是划分区域&#xff1a;b.地址空间的理解&#xff1a; 为什么要有进程空间&#xff1f;进一步理解页表与写时拷贝&#xff1a; 快速了解&#xff1a; 先来看这样一段…

2024年起重机司机(限桥式起重机)证考试题库及起重机司机(限桥式起重机)试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年起重机司机(限桥式起重机)证考试题库及起重机司机(限桥式起重机)试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作…

第四范式2023全年业绩:营收人民币42.0亿元同比增长36.4%,行业大模型为千行万业赋能...

3月20日&#xff0c;第四范式&#xff08;06682.HK&#xff09;公布2023年全年业绩&#xff0c;营收稳步增长&#xff0c;盈利节奏清晰。 第四范式定位人工智能时代的软件企业&#xff0c;致力于用人工智能技术赋能千行万业&#xff0c;帮助各行业发现更多规律&#xff0c;形成…

【排序】插入排序与选择排序详解

文章目录 &#x1f4dd;选择排序是什么&#xff1f;&#x1f320;选择排序思路&#x1f309; 直接选择排序&#x1f320;选择排序优化&#x1f320;优化方法&#x1f309;排序优化后问题 &#x1f320;选择排序效率特性 &#x1f309;插入排序&#x1f320;插入排序实现 &#…

day11【网络编程】-综合案例

day11【网络编程】 第三章 综合案例 3.1 文件上传案例 文件上传分析图解 【客户端】输入流&#xff0c;从硬盘读取文件数据到程序中。【客户端】输出流&#xff0c;写出文件数据到服务端。【服务端】输入流&#xff0c;读取文件数据到服务端程序。【服务端】输出流&#xf…

29-3 哥斯拉安装使用

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、哥斯拉 (Godzilla) 介绍 哥斯拉是一个基于流量、HTTP全加密的webshell管理工具,具有以下特点: 内置了3种Payload以及6种加密器,6种支持脚本后缀,20个内置插件基于Java,可…

Java最后一块石头的重量 II(力扣Leetcod1049)

最后一块石头的重量 II 力扣原题 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 x < y。那么粉碎的可能结…

Orbit 使用指南06 | 创建基础环境 | Isaac Sim | Omniverse

如是我闻&#xff1a; 环境将模拟的不同方面如场景、观测和行动空间、重置事件等汇集在一起&#xff0c;为各种应用创建一个连贯的接口。在Orbit中&#xff0c;环境是作为envs.BaseEnv和envs.RLTaskEnv类实现的。这两个类非常相似&#xff0c;但envs.RLTaskEnv对强化学习任务很…

LangChain模块介绍

LangChain模块介绍 Model I/O Prompts 提示词 Template 模板 复用Selector 提示词选择器 根据不同的条件选择不同的提示词 Language Models 语言模型 LLM 指代续写模型 Chat 对话形态的大语言模型 区分不同的语言模型 Output Parsers JSONStructured Data Connection ​ 构…