数据结构和算法(1) ---- Queue 的原理和实现

2024-06-24 04:52

本文主要是介绍数据结构和算法(1) ---- Queue 的原理和实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Queue 的定义和结构

队列(Queue) 是只允许在一端进行插入,在另一端进行删除的线性表
队列是一种先进先出(First In First Out)的线性表,简称 FIFO(First IN First OUT), 允许插入的一端称为队尾, 允许删除的一端称为队列头

队列的基本结构如下图所示:
queue struct

Queue 的抽象数据类型

队列也有线性表的各种操作,不同的是插入元素只能在队列尾,删除元素只能在对列头进行:
队列的抽象结构如下所示:

ADT Queue(队列)
Data:同线性表, 元素具有相同的类型,相邻的元素具有前驱和后继关系
Operation:InitQueue(Q*)DestroyQueue(Q*)isEmpty(Q*)isFull(Q*)dequeue(Q*, *e)enqueue(Q*, e)queueSize(Q)
endADT

队列有多种实现方式,比如 静态数组,动态数组,单链表,双链表等

静态数组实现Queue

静态数组实现队列的基本原理:

  • 建立一个 MAX_SIZE 的数组, 用于存放 Queue 中的元素
  • 建立int类型 queue->rear 代表队列尾, 每次 enqueue 一个元素时,queu->rear 指向最新的元素位置
    staticArrayEnqueue
  • 建立 queue->front 代表队列头, 每次 dequeue 一个元素,从 queue->front 位置处取出数据,并且最后其指向下一个元素位置
    StaticArrayDequeue
  • queue->rearqueue->front 相等时,queue->frontqueue->rear都重新设置为 0,此时队列为空,表示重新开始存储数据
    StaticArrayEqual
    参考代码如下:
#define MAX_SIZE 100
typedef struct {int data[MAX_SIZE];int front;// queue 尾端的索引int rear;
}Queue;void Queueinit(Queue* queue) {queue->front = -1;queue->rear = -1;
}int isEmpty(Queue* queue) {return (queue->front == -1 && queue->rear == -1);
};int isFull(Queue* queue) {// queue->rear == MAX_SIZE - 1  queue->front = 0//return (queue->rear + 1)%MAX_SIZE == queue->front;if((queue->rear + 1 - queue->front) == MAX_SIZE) {return 1;}return 0;
};void enqueue(Queue* queue,int item) {if(isFull(queue)) {fprintf(stderr,"queue is full. \n");return;}//printf("queue front is %d rear is %d \n",queue->front,queue->rear);if(isEmpty(queue)) {queue->rear = 0;queue->front = 0;} else {queue->rear = (queue->rear+1)%MAX_SIZE;}queue->data[queue->rear] = item;
}int dequeue(Queue* queue) {if(isEmpty(queue)) {fprintf(stderr,"queue is empty. \n");return -1;}int item = queue->data[queue->front];// with no elementif(queue->front == queue->rear) {printf("queue has no element backup to empty\n");queue->front = -1;queue->rear = -1;} else {queue->front = (queue->front +1)%MAX_SIZE;}return item;
}int peek(Queue* queue) {if(isEmpty(queue)) {fprintf(stderr,"queue is empty. \n");return -1;}return queue->data[queue->front];
}int testbasicQueueStaticArray(int agrc, char *argv[]) {{Queue testqueue = {.front = -1,.rear = -1,};Queueinit(&testqueue);for(int i = 0; i < 2000; i++) {enqueue(&testqueue,200+i);dequeue(&testqueue);}enqueue(&testqueue,1001);enqueue(&testqueue,1002);enqueue(&testqueue,1003);printf("dequeue item:%d \n", dequeue(&testqueue));printf("dequeue item:%d \n", dequeue(&testqueue));printf("dequeue item:%d \n", dequeue(&testqueue));printf("dequeue item:%d \n", dequeue(&testqueue));printf("peek queue element: %d queue size:%d\n", peek(&testqueue),QueueSize(&testqueue));}}
单链表实现Queue

单链表实现Queue的基本原理:

  • 建立一个单链表,包含指向队列头的指针queue->front 和指向队列尾的指针queue->rear

  • enqueue时,首先为新元素分配空间,然后插入到单链表的尾部,用queue->rear指向它
    LinkedListEnqueue

  • dequeue时,首先返回queue->front指向的节点内容,然后free掉queue->front节点,queue->front指向顺序的后一个节点
    LinkedListDequeue
    参考代码如下:

struct node {int data;struct node *next;
};typedef struct {struct node *front;struct node *rear;
}Queue;static int empty(Queue* queue){return (queue->front == NULL);
}static void initQueue(Queue* queue) {queue->front = queue->rear = NULL;
}static void push(Queue* queue, int value) {struct node *pnode;pnode = (struct node*)malloc(sizeof(struct node));if(pnode == NULL) {printf("malloc node failed!.\n");exit(1);}pnode->data = value;pnode->next = NULL;if(empty(queue)) {queue->front = pnode;queue->rear = pnode;} else {queue->rear->next= pnode;queue->rear = pnode;}
}static int pop(Queue* queue) {if (empty(queue)){printf("Queue Underflow. Unable to remove.\n");exit(1);}int item;struct node *p = queue->front;item = queue->front->data;queue->front = queue->front->next;if (queue->front == NULL) /* Queue contained only one node */queue->rear = NULL;free(p);return item;
}static int peek(Queue* queue) {if (empty(queue)){printf("Queue Underflow. Unable to remove.\n");exit(1);}return queue->front->data;
}static int queueSize(Queue* queue){struct node *p = queue->front;int count = 0;if(empty(queue)){return 0;}do {p = p->next;count++;}while(p != NULL);return count;
}int testbasicQueueImplsingleLinkedList(int agrc, char *argv[]) {{Queue testqueue;int qsize = 0;initQueue(&testqueue);push(&testqueue, 10);printf("queue size: %d. \n", queueSize(&testqueue));push(&testqueue, 101);push(&testqueue, 102);push(&testqueue, 103);push(&testqueue, 104);printf("queue size: %d. \n", queueSize(&testqueue));printf("pop value: %d queue size: %d. \n", pop(&testqueue), qsize);qsize = queueSize(&testqueue);printf("pop value: %d queue size: %d. \n", pop(&testqueue), qsize);qsize = queueSize(&testqueue);printf("pop value: %d queue size: %d. \n", pop(&testqueue), qsize);qsize = queueSize(&testqueue);printf("pop value: %d queue size: %d. \n", pop(&testqueue), qsize);printf("queue size: %d. \n", queueSize(&testqueue));printf("peek value: %d  \n", peek(&testqueue));printf("queue size: %d. \n", queueSize(&testqueue));}return 1;
}

这篇关于数据结构和算法(1) ---- Queue 的原理和实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1089220

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

通过SSH隧道实现通过远程服务器上外网

搭建隧道 autossh -M 0 -f -D 1080 -C -N user1@remotehost##验证隧道是否生效,查看1080端口是否启动netstat -tuln | grep 1080## 测试ssh 隧道是否生效curl -x socks5h://127.0.0.1:1080 -I http://www.github.com 将autossh 设置为服务,隧道开机启动

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

代码随想录算法训练营:12/60

非科班学习算法day12 | LeetCode150:逆波兰表达式 ,Leetcode239: 滑动窗口最大值  目录 介绍 一、基础概念补充: 1.c++字符串转为数字 1. std::stoi, std::stol, std::stoll, std::stoul, std::stoull(最常用) 2. std::stringstream 3. std::atoi, std

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 📚 前言 📑摘要 📑系统流程 📚 系统架构设计 📚 数据库设计 📚 系统功能的具体实现    💬 系统登录注册 系统登录 登录界面   用户添加  💬 抗疫列表展示模块     区域信息管理 添加物资详情 抗疫物资列表展示 抗疫物资申请 抗疫物资审核 ✒️ 源码实现 💖 源码获取 😁 联系方式 📚 前言 📑博客主页:

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

探索蓝牙协议的奥秘:用ESP32实现高质量蓝牙音频传输

蓝牙(Bluetooth)是一种短距离无线通信技术,广泛应用于各种电子设备之间的数据传输。自1994年由爱立信公司首次提出以来,蓝牙技术已经经历了多个版本的更新和改进。本文将详细介绍蓝牙协议,并通过一个具体的项目——使用ESP32实现蓝牙音频传输,来展示蓝牙协议的实际应用及其优点。 蓝牙协议概述 蓝牙协议栈 蓝牙协议栈是蓝牙技术的核心,定义了蓝牙设备之间如何进行通信。蓝牙协议

python实现最简单循环神经网络(RNNs)

Recurrent Neural Networks(RNNs) 的模型: 上图中红色部分是输入向量。文本、单词、数据都是输入,在网络里都以向量的形式进行表示。 绿色部分是隐藏向量。是加工处理过程。 蓝色部分是输出向量。 python代码表示如下: rnn = RNN()y = rnn.step(x) # x为输入向量,y为输出向量 RNNs神经网络由神经元组成, python