数据结构-栈和队列

栈和队列

    • 栈的基本概念
    • 栈的结构
    • 初始化栈
    • 销毁栈
    • 压栈
    • 出栈
    • 栈中元素的个数
    • 查找栈顶的元素
    • 压栈和出栈的一个演示
    • 全部代码
      • Stack.h
      • Stack.c
      • Test.c
  • 队列
    • 队列的基本概念
    • 节点和队列的定义
    • 队列的初始化
    • 销毁队列
    • 入队
    • 出队
    • 计算队列中元素的个数
    • 判断队列是否为空
    • 返回队列中的队头元素
    • 返回队列中的队尾元素
    • 队列的一个演示过程
    • 全部代码
      • Queue.h
      • Queue.c
      • Test.c

栈的基本概念

在这里插入图片描述

我们选用数组的形式来构成栈

栈的结构

以一个结构体的形式来表示栈的一些信息

typedef struct Stack
{STDataType* a;int top;//表示栈顶位置,也表示已存储的数据个数int capacity;//
}ST;

初始化栈

初始化结构体的各个成员,对指针所在位置开辟空间

void STInit(ST* ps)
{assert(ps);ps->a=(STDataType*)malloc(sizeof(STDataType)*4);if(ps->a==NULL){perror("malloc fail");return;}ps->top = 0;ps->capacity = 4;
}

销毁栈

对于malloc函数开辟的空间要释放掉,其它置0

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

压栈

空间不够,先开辟空间;给数据,然后top++

void STPush(ST* ps,STDataType x)
{assert(ps);if (ps->top==ps->capacity){STDataType* temp=(STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);if (temp==NULL){perror("realloc fail");return;}ps->a = temp;ps->capacity = ps->capacity * 2;}ps->a[ps->top] = x;ps->top++;
}

出栈

只需要动top的值即可,但是要确保栈中存在元素,用一个函数STEmpty来判断

bool STEmpty(ST* ps)
{assert(ps);return ps->top==0;
}
void STPop(ST* ps)
{assert(ps);assert(!STEmpty(ps));ps->top--;
}

栈中元素的个数

直接返回top

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

查找栈顶的元素

要先判断栈中是否含有元素,直接返回栈顶的元素(此处的top已经是++之后的,所以需要-1)

STDataType STTop(ST* ps)
{ assert(ps);assert(!STEmpty(ps));return ps->a[ps->top-1];
}

压栈和出栈的一个演示

如下:

int main()
{ST plist;STInit(&plist);STPush(&plist, 1);STPush(&plist, 2);STPush(&plist, 3);STPop(&plist);STPush(&plist, 4);//打印方式,先返回栈顶的元素,再出栈while (!STEmpty(&plist)){printf("%d ", STTop(&plist));STPop(&plist);}STDestroy(&plist);return 0;
}

结果如下:
在这里插入图片描述

全部代码

Stack.h

#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.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);bool STEmpty(ST* ps);//栈中元素的个数
int STSize(ST* ps);//查找栈顶的元素
STDataType STTop(ST* ps);

Stack.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "Stack.h"void STInit(ST* ps)
{assert(ps);ps->a=(STDataType*)malloc(sizeof(STDataType)*4);if(ps->a==NULL){perror("malloc fail");return;}ps->top = 0;ps->capacity = 4;
}void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}void STPush(ST* ps,STDataType x)
{assert(ps);if (ps->top==ps->capacity){STDataType* temp=(STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);if (temp==NULL){perror("realloc fail");return;}ps->a = temp;ps->capacity = ps->capacity * 2;}ps->a[ps->top] = x;ps->top++;
}bool STEmpty(ST* ps)
{assert(ps);return ps->top==0;
}
void STPop(ST* ps)
{assert(ps);assert(!STEmpty(ps));ps->top--;
}int STSize(ST* ps)
{assert(ps);return ps->top;
}STDataType STTop(ST* ps)
{ assert(ps);assert(!STEmpty(ps));return ps->a[ps->top-1];
}

Test.c

#define _CRT_SECURE_NO_WARNINGS 1#include "Stack.h"int main()
{ST plist;STInit(&plist);STPush(&plist, 1);STPush(&plist, 2);STPush(&plist, 3);STPop(&plist);STPush(&plist, 4);//打印方式,先返回栈顶的元素,再出栈while (!STEmpty(&plist)){printf("%d ", STTop(&plist));STPop(&plist);}STDestroy(&plist);return 0;
}

队列

队列的基本概念

在这里插入图片描述

用单链表的方式来实现队列
基本组成元素为链表的单个节点,由于队列的性质,需要知道队头和队尾,同时我们还想知道队列中元素的个数
单个节点属于队列的局部,而队头和队尾属于队列,地位处于节点之上,这种情况下需要用结构体嵌套来表示

节点和队列的定义

//单个节点
typedef struct QueneNode
{struct QueneNode* next;QDataType data;
}QNode;//整个队列
typedef struct Quene
{QNode* head;QNode* tail;int size;
}Quene;

队列的初始化

需要对pq进行断言,因为当pq所指向的空间为空时,其嵌套的结构体QNode将不存在,这不符合队列的要求。只对队列结构体初始化

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

销毁队列

同销毁链表一致,同时head和tail置空,size置0

void QueueDestroy(Quene* 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(Quene* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode==NULL){perror("malloc fail");return;}newnode->next = NULL;newnode->data = x;//需要判断队列中是否有元素if (pq->head==NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}

出队

要保证队列中有元素,之后头删

void QueuePop(Quene* pq)
{assert(pq);//确保有队列assert(pq->head != NULL);//确保队列不为空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--;
}

计算队列中元素的个数

直接返回结构体中的size

int QueueSize(Quene* pq)
{assert(pq);return pq->size;
}

判断队列是否为空

bool QueueEmpty(Quene* pq)
{assert(pq);return pq->size==0;
}

返回队列中的队头元素

要确保队列中有元素

QDataType QueueFront(Quene* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}

返回队列中的队尾元素

要确保队列中有元素

QDataType QueueBack(Quene* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}

队列的一个演示过程

int main()
{Quene q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePop(&q);QueuePush(&q, 3);while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}QueueDestroy(&q);return 0;
}

结果如下:
在这里插入图片描述

全部代码

Queue.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>typedef int QDataType;//单个节点
typedef struct QueneNode
{struct QueneNode* next;QDataType data;
}QNode;//整个队列
typedef struct Quene
{QNode* head;QNode* tail;int size;
}Quene;//初始化
void QueueInit(Quene* pq);
//销毁
void QueueDestroy(Quene* pq);//入队
void QueuePush(Quene* pq, QDataType x);
//出队
void QueuePop(Quene* pq);//计算队列中元素的个数
int QueueSize(Quene* pq);
//判断队列是否为空
bool QueueEmpty(Quene* pq);//队列中的队头元素
QDataType QueueFront(Quene* pq);
//队列中的队尾元素
QDataType QueueBack(Quene* pq);

Queue.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"void QueueInit(Quene* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}void QueueDestroy(Quene* 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(Quene* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode==NULL){perror("malloc fail");return;}newnode->next = NULL;newnode->data = x;//需要判断队列中是否有元素if (pq->head==NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}void QueuePop(Quene* pq)
{assert(pq);//确保有队列assert(pq->head != NULL);//确保队列不为空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--;
}int QueueSize(Quene* pq)
{assert(pq);return pq->size;
}bool QueueEmpty(Quene* pq)
{assert(pq);return pq->size==0;
}QDataType QueueFront(Quene* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}QDataType QueueBack(Quene* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}

Test.c

#define _CRT_SECURE_NO_WARNINGS 1#include "Queue.h"int main()
{Quene q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePop(&q);QueuePush(&q, 3);while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}QueueDestroy(&q);return 0;
}

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

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

相关文章

暑期代码每日一练Day3:874. 模拟行走机器人

题目 874. 模拟行走机器人 分析 这道题就是个简单的模拟 主要有两点考察点&#xff1a; 对方向数组的运用 方向数组存储的是各个方向的单位向量&#xff0c;也即&#xff1a; 方向XY向北01向东10向南0-1向西-10 存储在数组中&#xff0c;则是方向数组&#xff1a; in…

Spring(一):Spring 的创建和使用

目录 Spring 是什么&#xff1f; 什么是容器&#xff1f; 什么是 IoC&#xff1f; 什么是 IoC&#xff1f; IoC的优点是啥呢&#xff1f; 理解 IoC DI 概念说明 Spring 的创建 创建 Spring 项目 1. 创建⼀个普通 Maven 项⽬。 2. 添加 Spring 框架⽀持&#xff08;s…

基于FPGA的按键消抖

文章目录 基于FPGA的按键消抖一、按键消抖原理二、按键消抖代码三、仿真代码编写四&#xff1a;总结 基于FPGA的按键消抖 一、按键消抖原理 按键抖动&#xff1a;按键抖动通常的按键所用开关为机械弹性开关&#xff0c;当机械触点断开、闭合时&#xff0c;由于机械触点的弹性…

uboot移植裁剪原理和流程

一、Uboot的裁剪是裁剪什么&#xff1f; Uboot的裁剪分为两个方面&#xff1a;Uboot本身命令的裁剪和具体SoC硬件配置的裁剪。 1、Uboot本身命令的裁剪   Uboot提供了很多的操作命令&#xff0c;我们使用Uboot的时候通常只使用最常用的一些命令&#xff0c;其他很多的命令有…

类 和 对象

目录 1、面向对象编程 2、面向对象编程 2.1面向对象编程特征 3、类和对象的概念 3.1类的定义 3.11属性 3.12方法 3.13重载 3.14递归 3.13返回值return 3.2对象 3.2.1对象组合 4、jvm内主要三块内存空间 5、参数传值 1、面向对象编程 面向过程&#xff1a;关注的是步骤…

webpack笔记二

文章目录 背景拆分环境清除上次构建产物插件&#xff1a;clean-webpack-plugin合并配置文件插件&#xff1a;webpack-merge实时更新和预览效果&#xff1a;webpack-dev-server babel配置参考 背景 webpack笔记一 在前面的学习&#xff0c;完成了webpack的基本配置&#xff0c…

【云原生】k8s之包管理器Helm

前言 每个成功的软件平台都有一个优秀的打包系统&#xff0c;比如Debian、Ubuntu 的 apt&#xff0c;RedHat、CentOS 的 yum。Helm 则是 Kubernetes上 的包管理器&#xff0c;方便我们更好的管理应用。 1.Helm的相关知识 1.1 Helm的简介与了解 Helm本质就是让K8s的应用管理&…

Profibus DP主站转Modbus TCP网关profibus从站地址范围

远创智控YC-DPM-TCP网关。这款产品在Profibus总线侧实现了主站功能&#xff0c;在以太网侧实现了ModbusTcp服务器功能&#xff0c;为我们的工业自动化网络带来了全新的可能。 远创智控YC-DPM-TCP网关是如何实现这些功能的呢&#xff1f;首先&#xff0c;让我们来看看它的Profib…

Linux 学习记录52(ARM篇)

Linux 学习记录52(ARM篇) 本文目录 Linux 学习记录52(ARM篇)一、汇编语言相关语法1. 汇编语言的组成部分2. 汇编指令的类型3. 汇编指令的使用格式 二、基本数据处理指令1. 数据搬移指令(1. 格式(2. 指令码类型(3. 使用示例 2. 立即数(1. 一条指令的组成 3. 移位操作指令(1. 格式…

Meta 最新发布 LLaMA 2(允许商业化)

2023年7月18日&#xff0c;Meta 发布了LLaMA 2&#xff0c;包含7B&#xff0c;13B&#xff0c;70B三种参数&#xff08;34B暂时还未发布&#xff09;。 官方&#xff1a; https://ai.meta.com/llama/ 论文&#xff1a;Llama 2: Open Foundation and Fine-Tuned Chat Models 模型…

网络编程——RPC与HTTP基本介绍、历史追溯、主流应用场景、对比分析、为什么还需要使用RPC

一、HTTP与RPC基本介绍 HTTP协议&#xff08;Hyper Text Transfer Protocol&#xff09;超文本传输协议&#xff1a; 一个用于在网络上交换信息的标准协议&#xff0c;它定义了客户端(例如浏览器)和服务器之间的通信方式。如平时上网在浏览器上敲个网址url就能访问网页&#x…

关于电脑显示器屏幕看不出灰色,灰色和白色几乎一样无法区分,色彩调整方法

问题&#xff1a; 电脑显示器屏幕看不出灰色&#xff0c;灰色和白色几乎一样无法区分。白色和灰色有色差。 解决方法&#xff1a; 打开“控制面板” ->“色彩管理” ->“高级” ->“校正显示器” 在下一步调节中调成中间这一个实例的样子就可以了 进行微调&#x…