数据结构-----对列

news2024/11/14 14:42:37

前言

Hello, 小伙伴们,你们的作者菌又来了,前不久,我们学习了一种数据结构----栈,他特殊的性质使得他在一些数据管理的问题上被广泛的使用,那今天,我们就来学习另一种十分重要的数据结构--对列。

在开始之间,还是按例求三,如果你喜欢我的内容,就请不要忘记,点赞、评论和收藏,你们的支持就是我更新的动力,万分感谢!!

好,我们先在开始。

1.队列的介绍

基本概念:

只允许在⼀端进⾏插⼊数据操作,在另⼀端进⾏删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)

入队列:进行插入操作的一段为队尾;

出队列:进行删除操作的一端称为对头。

队列的底层结构选型:

队列也可以用数组和链表的方式链实现,使用链表的结构实现会更加的优秀,因为如果使用数组的结构,出队列在数组的头部进行,效率会十分底下!! 

2.队列的实现

我门还是先创建三个文件(就向实现其他数据结构一样):

 2.1队列结构的定义:

typedef int QDataType;
typedef struct QueueNode
{
	QDataType x;
	struct QueueNode* next;
}QueueNode;

typedef struct Queue
{
	QueueNode* phead;
	QueueNode* ptail;
}Queue;

怎样来理解这样的定义呢?

队列的定义底层使用的确实是单链表的结构,但是特殊的就是,他只能在头部出数据,只能在为部插入数据,所以,我们可以使用两个结构体,来实现队列:

phead用于出数据;

ptail用于输入数据。

 2.2队列的初始化(QueueIit函数的实现)

2.2.1函数的定义

//初始化队列
void QueueInit(Queue* ps);

2.2.2函数的实现

//初始化队列
void QueueInit(Queue* ps)
{
	assert(ps);
	ps->phead = ps->ptail = NULL;
}

初始化的操作与单链表相似。

代码测试:

2.3队列的数据插入(QueuePush函数的实现)

2.3.1 函数的定义

//入队列
void QueuePush(Queue* ps, QDataType  x);

这个也和单链表的结构相似,但是要注意几点,我们先来看函数的是实现代码:

2.3.2函数的实现


QueueNode* BuyNode(QDataType x)
{
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc Fail!!");
		exit(1);
	}
	newnode->x = x;
	newnode->next = NULL;
	return newnode;
}
//队列的销毁

void QueuePush(Queue* ps, QDataType  x)
{
	assert(ps);
	QueueNode* New = BuyNode(x);
	if (ps->phead == NULL)
	{
		ps->phead = ps->ptail = New;
	}
	else
	{
		ps->ptail->next = New;
		ps->ptail = ps->ptail->next;
	}
}

1.我们注意不要将QueueNode 和Queue的结构混淆;

2.一定要记得,将新节点的next指针置位NULL;

3.要考虑到ps->phead 和 ps->ptail都为NULL的情况!!

代码测试:

 

入队列的操作就完成了!! 

2.4队列的出数据 (QueuePop函数的实现)

2.4.1函数的定义:

//出队列
void QueuePop(Queue* ps);

2.4.2代码的实现

这里的出队列,其实和单链表的头删是一个逻辑,还是要考虑到一下几点:

1.删除数据的前提是,队列中有元素可删!

2.不能将队列删除为NULL后,任然删除数据!!

bool IsEmpty(Queue* ps)
{
	return ps->phead == NULL;
}
//IsEmpty函数可以判断队列存储数据的情况
void QueuePop(Queue* ps)
{
	assert(ps);
	assert(!IsEmpty(ps));
	QueueNode* ret = ps->phead->next;
	free(ps->phead);
	ps->phead = ret;
}

 代码测试:

2.5取队列的头(尾)数据(QueueTop 函数和 QueueBack函数的实现)

2.5.1函数的定义

//取对头数据
QDataType QueueTop(Queue* ps);
//取队尾数据
QDataType QueueBack(Queue* ps);

这样的操作十分的简单,就和前面我们学习栈的时候,取数据的操作大致相同

2.5.2函数的实现

//取对头数据
QDataType QueueTop(Queue* ps)
{
	assert(ps && !IsEmpty(ps));
	return ps->phead->x;
}
//取队尾数据
QDataType QueueBack(Queue* ps)
{
	assert(ps && !IsEmpty(ps));
	return ps->ptail->x;
}

 这样的操作十分的简单,我们只需要确保队列中有元素,就可以取出队头和对尾元素。

接下来我们来测试一下,看看能不能达到我们想要的效果:

2.6队列中的数据个数 

在这里,我们可以先写一个函数CountSize来解决这样的问题:

//得出队列中的数据元素个数
int CountSize(Queue* ps);
int CountSize(Queue* ps)
{
	assert(ps);
	QueueNode* pcur = ps->phead;
	int size = 0;
	while (pcur)
	{
		size++;
		pcur = pcur->next;
	}
	return size;
}

经过测试,我们可知,这样是可以解决问题的,但是这样做是绝对不规范的!! 

因为队列和栈一样,不能被遍历,也不能被随机的访问!!

同时,如果外界的用户要进行频繁的数据个数获取,我们出于时间复杂度的考虑,因该怎样来修改我们的代码呢? 

所以,我们要怎样才能解决问题呢?

或许,我们在定义队列的节点时,就加上一个元素,来记录我们插入数据的个数

如,这是我们原来的队列定义:

typedef int QDataType;
typedef struct QueueNode
{
	QDataType x;
	struct QueueNode* next;
}QueueNode;

typedef struct Queue
{
	QueueNode* phead;
	QueueNode* ptail;
}Queue;

我们可以修改为

typedef int QDataType;
typedef struct QueueNode
{
	QDataType x;
	struct QueueNode* next;
}QueueNode;

typedef struct Queue
{
	QueueNode* phead;
	QueueNode* ptail;
    int size;//增加一个元素来记录存储数据的个数!!
}Queue;

每插入一次数据,我们就然size++;

每出一次队列,size--;

在要获取元素个数时,我们只需要,将size返回就行!所以,我们可以来试试这样的方法:

所以CountSize我们可以改写为 

int CountSize(Queue* ps)
{
	assert(ps);
	return ps->size;
}

接下来,我们来测试一下:

 

 2.7队列的销毁(QueueDstroy函数的实现)

 2.7.1函数的定义:

void QueueDstroy(Queue* ps);
//队列的销毁

2.7.2函数的实现 

void QueueDestroy(Queue* ps)
{
	assert(ps && !IsEmpty(ps));
	QueueNode* ret = ps->phead;
	while (ret)
	{
		QueueNode* next = ret->next;
		free(ret);
		ret = next;
	}
	ps->ptail = ps->phead = NULL;
	ps->size = 0;
}

销毁的操作和之前链表的操作相似,如果对链表的知识掌握的够好,我们可以直接仿写!!

3.代码展示:

3.1Queu.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>

typedef int QDataType;
typedef struct QueueNode
{
	QDataType x;
	struct QueueNode* next;
}QueueNode;

typedef struct Queue
{
	QueueNode* phead;
	QueueNode* ptail;
	int size;

}Queue;

//初始化队列
void QueueInit(Queue* ps);
//队列的销毁
void QueueDestroy(Queue* ps);
//入队列
void QueuePush(Queue* ps, QDataType  x);
//出队列
void QueuePop(Queue* ps);

//取对头数据
QDataType QueueTop(Queue* ps);
//取队尾数据
QDataType QueueBack(Queue* ps);


//得出队列中的数据元素个数
int CountSize(Queue* ps);
bool IsEmpty(Queue* ps);

3.2Queue.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"Queue.h"

//初始化队列
void QueueInit(Queue* ps)
{
	assert(ps);
	ps->phead = ps->ptail = NULL;
	ps->size = 0;
}
void QueueDestroy(Queue* ps)
{
	assert(ps && !IsEmpty(ps));
	QueueNode* ret = ps->phead;
	while (ret)
	{
		QueueNode* next = ret->next;
		free(ret);
		ret = next;
	}
	ps->ptail = ps->phead = NULL;
	ps->size = 0;
}

QueueNode* BuyNode(QDataType x)
{
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc Fail!!");
		exit(1);
	}
	newnode->x = x;
	newnode->next = NULL;
	return newnode;
}

void QueuePush(Queue* ps, QDataType  x)
{
	assert(ps);
	QueueNode* New = BuyNode(x);
	if (ps->phead == NULL)
	{
		ps->phead = ps->ptail = New;
	}
	else
	{
		ps->ptail->next = New;
		ps->ptail = New;
	}
	ps->size++;
}
bool IsEmpty(Queue* ps)
{
	return ps->phead == NULL;
}
void QueuePop(Queue* ps)
{
	assert(ps);
	assert(!IsEmpty(ps));
	QueueNode* ret = ps->phead->next;
	free(ps->phead);
	ps->phead = ret;
	ps->size--;
}
//取对头数据
QDataType QueueTop(Queue* ps)
{
	assert(ps && !IsEmpty(ps));
	return ps->phead->x;
}
//取队尾数据
QDataType QueueBack(Queue* ps)
{
	assert(ps && !IsEmpty(ps));
	return ps->ptail->x;
}
//得出队列中的数据元素个数
int CountSize(Queue* ps)
{
	assert(ps);
	return ps->size;
}

3.3test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"
void Test()
{
	Queue  s;
	QueueInit(&s);
	QueuePush(&s, 0);
	QueuePush(&s, 1);
	QueuePush(&s, 2);
	QueuePop(&s);
	//取对头数据
	printf("Top:%d\n", QueueTop(&s));
	//取队尾数据
	printf("Back:%d\n", QueueBack(&s));
	printf("Size:%d\n", CountSize(&s));
	QueueDestroy(&s);
	printf("Size:%d\n", CountSize(&s));
}

int main()
{
	Test();
	return 0;
}

好,今天的学习就到这里,我们下期再见,拜拜!!!

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

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

相关文章

Spring Boot中如何实现全链路调用日志跟踪?

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 引言 在Spring Boot中实现全链路调用日志跟踪&#xff0c;主要依赖于Mapped Diagnostic Context&#xff08;MDC&#xff09;功能。MDC是一种用于在多线程条件下记录日志的功能&#xff0c;它可以看作是与当…

C++ | Leetcode C++题解之第283题移动零

题目&#xff1a; 题解&#xff1a; class Solution { public:void moveZeroes(vector<int>& nums) {int n nums.size(), left 0, right 0;while (right < n) {if (nums[right]) {swap(nums[left], nums[right]);left;}right;}} };

[Python][列表和元组]详细讲解

目录 0.是什么&#xff1f;1.列表1.创建列表2.访问下标3.切片操作4.遍历列表元素5.新增元素6.查找元素7.删除元素8.连接列表 2.关于元组∞.积累 0.是什么&#xff1f; 列表和元组类似C/C中的数组列表&#xff1a;一种在代码中批量表示/保存数据的方式 代码中需要表示的数据特别…

093、Python操作Excel生成统计图表

在Excel里做统计表是我们经常会做的一件事情。我们也可以通过编程的方式操作Excel生成统计图表。 下面是官方的一个很有参考价值的案例&#xff1a; from openpyxl import Workbook from openpyxl.chart import BarChart, Reference from copy import deepcopywb Workbook(w…

C# 使用pythonnet 迁入 python 初始化错误解决办法

pythonnet 从 3.0 版本开始&#xff0c;必须设置Runtime.PythonDLL属性或环境变量 例如&#xff1a; string pathToVirtualEnv ".\\envs\\pythonnetTest"; Runtime.PythonDLL Path.Combine(pathToVirtualEnv, "python39.dll"); PythonEngine.PythonHom…

vscode 调试web后端

1、调试环境配置 一、安装python环境管理器 其中要先在vscode选择对应的python环境&#xff0c;最方便的是按照环境管理器后从中选择。其中在【externsions】里面安装python即可。 如下&#xff1a; 二、编写launch.json文件 其中如下&#xff1a; {// Use IntelliSense …

GraphHopper-map-navi_路径规划、导航(web前端页面版)

文章目录 一、项目地址二、踩坑环境三、问题记录3.1、graphhopper中地图问题3.1.1. getOpacity不存在的问题3.1.2. dispatchEvent不存在的问题3.1.3. vectorLayer.set(background-maplibre-layer, true)不存在set方法3.1.4. maplibre-gl.js.map不存在的问题3.1.5. Uncaught Ref…

AWS-Lambda的使用

介绍 Lambda 是一种无服务器(Serverless), 而且设计成事件驱动的计算服务器. 简单来说, 你可以将你的 code 上传, 当有事件产生(例如cronjob , 或者S3有新的文件被上传上來) , 你的code 就会在瞬间(零点几秒以內)被叫起來执行. 由于你不用管 Server如何维护, 或者自动扩展之类…

数据结构第二讲:顺序表

数据结构第二讲&#xff1a;顺序表 1.线性表2.什么是顺序表3. 静态顺序表4.动态顺序表4.1顺序表基础4.2顺序表的初始化4.3顺序表的销毁4.4顺序表的尾插4.5顺序表的头插4.6顺序表的尾删4.7顺序表的头删4.8顺序表在指定位置之前插入数据4.9顺序表删除指定位置的数据4.10顺序表查找…

ubuntu22.04 安装 NVIDIA 驱动以及CUDA

目录 1、事前问题解决 2、安装 nvidia 驱动 3、卸载 nvidia 驱动方法 4、安装 CUDA 5、安装 Anaconda 6、安装 PyTorch 1、事前问题解决 在安装完ubuntu之后&#xff0c;如果进入ubuntu出现黑屏情况&#xff0c;一般就是nvidia驱动与linux自带的不兼容&#xff0c;可以通…

AMQP-核心概念-4

本文参考以下链接摘录翻译&#xff1a; https://www.rabbitmq.com/tutorials/amqp-concepts 绑定 (Bindings) 绑定是交换机用来将消息路由到队列的规则。为了让一个交换机E将消息路由到队列Q&#xff0c;Q必须绑定到E。绑定可以有一个可选属性routing key&#xff0c;有一些类…

uart开发调试

1. Uart基本框架 1.1概念 通信系统有两种方式&#xff0c;同步通信和异步通信. 同步通信的典型特征&#xff1a;通信双方公用同一个时钟&#xff0c;发送/接受速率完全一致&#xff0c;通信时需要带时钟信号传输. 异步通信的典型特征&#xff1a;通信双方各自具有独立的时钟…

电脑为什么会出现“找不到msvcr120.dll无法执行代码”?如何解决msvcr120.dll丢失错误

在使用电脑的过程中不知带大家有没有遇到过“找不到msvcr120.dll无法执行代码”的错误提示的情况&#xff0c;出现这样的情况大家都有什么解决办法可以解决&#xff1f;有什么办法能够帮助大家修复丢失的msvcr120.dll文件。接下来这篇文章就将教大家修复“找不到msvcr120.dll无…

Vue3-拉开序幕的setup

Vue3 中的 setup 是一个新的配置项&#xff0c;值是一个函数。 export default {name: App,setup: function () {} } </script> 和 Vue2 中的 data 一样&#xff0c;我也可以将 setup 简写成为 export default {name: App,setup() {} } setup函数的使用 与 Vue2 不一样…

刷题计划 day4 【双指针、快慢指针、环形链表】链表下

⚡刷题计划day4继续&#xff0c;可以点个免费的赞哦~ 下一期将会开启哈希表刷题专题&#xff0c;往期可看专栏&#xff0c;关注不迷路&#xff0c; 您的支持是我的最大动力&#x1f339;~ 目录 ⚡刷题计划day4继续&#xff0c;可以点个免费的赞哦~ 下一期将会开启哈希表刷题…

十一、【Python】基础教程-【Python全掌握】六大基础数据类型:布尔类型的终极指南

目录 一、基础类型“布尔型”处理方法 1. 直接赋值和使用 2. 布尔值的逻辑运算 3. 条件语句中的布尔值 4. 布尔值转换 5. 短路逻辑 6. 在循环和迭代中的使用 一、基础类型“布尔型”处理方法 在Python中&#xff0c;布尔类型是一种基本的数据类型&#xff0c;用于表示逻…

MySQL 索引相关基本概念

文章目录 前言一. B Tree 索引1. 概念2. 聚集索引/聚簇索引3. 辅助索引/二级索引4. 回表5. 联合索引/复合索引6. 覆盖索引 二. 哈希索引三. 全文索引 前言 InnoDB存储引擎支持以下几种常见索引&#xff1a;BTree索引&#xff0c;哈希索引&#xff0c;全文索引 一. B Tree 索引…

1、hadoop环境搭建

1、环境配置 ip(/etc/sysconfig/network-scripts) # 网卡1 DEVICEeht0 TYPEEthernet ONBOOTyes NM_CONTROLLEDyes BOOTPROTOstatic IPADDR192.168.59.11 GATEWAY192.168.59.1 NETMASK 255.255.255.0 # 网卡2 DEVICEeht0 TYPEEthernet ONBOOTyes NM_CONTROLLEDyes BOOTPROTOdh…

均匀圆形阵列原理及MATLAB仿真

均匀圆形阵列原理及MATLAB仿真 目录 前言 一、均匀圆阵原理 二、圆心不存在阵元方向图仿真 三、圆心存在阵元方向图仿真 四、MATLAB仿真代码 总结 前言 本文详细推导了均匀圆形阵列的方向图函数&#xff0c;对圆心不放置阵元和圆心放置阵元的均匀圆形阵列方向图都进行了仿…

前端JS特效第57波:响应式博客网站图文幻灯片

响应式博客网站图文幻灯片&#xff0c;先来看看效果&#xff1a; 部分核心的代码如下&#xff1a; <!DOCTYPE html> <html lang"zh-CN"><head> <meta charset"utf-8"> <title>响应式博客幻灯片演示</title><link …