【数据结构】队列

devtools/2024/12/22 13:18:53/

一、介绍

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。

二、队列的实现方法

1、队列的数组实现

1.在实例化队列时确定数组大小并初始化数组。

2.队列功能:

① 插入元素(元素在队尾入队)push(int num)

② 删除元素(在队头元素出队)pop()

③ 查看队头元素(只查看,不删除)front()

④ 判空 isEmpty()

⑤ 判满 isFull()

⑥ 查看队列长度 length()

⑦ 清空队列 clear()

3.代码实现

(1)定长数组实现

#include <iostream>
#include <string>
using namespace std;class Myqueue
{
private:int head,tail;//队头指针,对尾指针int count;//记录队列元素数量int size;//队列容量(数组初始化大小)int* data;//数组
public:Myqueue(int capacity);~Myqueue();void push(int num);void front();void pop();bool isEmpty();bool isFull();int length();
};Myqueue::Myqueue(int capacity)
{head=0,tail=0;count=0;size=capacity;data=new int[capacity];}Myqueue::~Myqueue()
{delete []data;
}void Myqueue::push(int num)
{if(isFull()){std::cout<<"error"<<std::endl;return;}data[tail]=num;tail=(tail+1)%size;count++;}void Myqueue::front()
{if(isEmpty()){std::cout<<"error"<<std::endl;}else{std::cout<<data[head]<<std::endl;}}void Myqueue::pop()
{if(isEmpty()){std::cout<<"error"<<std::endl;}else{std::cout<<data[head]<<std::endl;head=(head+1)%size;count--;}
}bool Myqueue::isEmpty()
{return count==0;
}bool Myqueue::isFull()
{return count==size;
}bool Myqueue::length()
{return count;
}void Myqueue::clear()
{while(head!=tail){pop();}
}

(2)环形数组实现

#include <iostream>
#include <vector>
using namespace std;/* 基于环形数组实现的队列 */
class ArrayQueue {
public:ArrayQueue(int capacity);~ArrayQueue();int capacity();//获取队列容量int size();//获取队列长度bool isEmpty();  //队列判空void push(int num);//元素入队int peek();     //返回队首元素int pop();      //元素出队vector<int> toVector();private:int* nums;       // 用于存储队列元素的数组int front;       // 队首指针,指向队首元素int queSize;     // 队列长度int queCapacity; // 队列容量};ArrayQueue::ArrayQueue(int capacity):queCapacity(capacity),queSize(0),front(0),nums(new int[capacity])
{
}ArrayQueue::~ArrayQueue()
{delete[] nums;
}/* 获取队列的容量 */
int ArrayQueue::capacity()
{return queCapacity;
}/* 获取队列的长度 */
int ArrayQueue::size()
{return queSize;
}/* 判断队列是否为空 */
bool ArrayQueue::isEmpty()
{return queSize == 0;
}/* 入队 */
void ArrayQueue::push(int num)
{if (queSize == queCapacity){std::cout << "队列已满" << std::endl;return;}//计算队尾指针,指向队尾索引+1//这是一个环形数组,通过取余操作实现rear越过数组尾部后回到头部int rear = (front + queSize) % queCapacity;nums[rear] = num;queSize++;}/* 访问队首元素 */
int ArrayQueue::peek()
{if (isEmpty()){throw out_of_range("队列为空");}return nums[front];
}/* 出队 */
int ArrayQueue::pop()
{int num = peek();//队首指针向后移动一位,若越过尾部,则返回到数组头部front = (front + 1) % queCapacity;--queSize;return num;
}/* 将数组转化为 Vector 并返回 */
vector<int> ArrayQueue::toVector()
{vector<int> arr(queSize);//仅转换有效长度范围内的列表元素for (int i = 0, j = front; i < queSize; i++, j++){arr[i] = nums[j % queCapacity];}return arr;
}

2、队列的链表实现

#include <iostream>
#include <vector>
using namespace std;/* 链表节点结构体 */
struct ListNode
{int val;ListNode* next;ListNode(int x) : val(x), next(nullptr) {}  // 构造函数
};class LinkedListQueue {
private:ListNode* front, *rear; // 头节点 front ,尾节点 rearint queSize;
public:LinkedListQueue();~LinkedListQueue();int size();			//获取队列长度bool isEmpty();		//判断队列是否为空void push(int num);	//入队int pop();			//出队int peek();			//访问队首元素vector<int> toVector(); //链表转换为vector
};LinkedListQueue::LinkedListQueue():front(nullptr),rear(nullptr),queSize(0)
{}LinkedListQueue::~LinkedListQueue()
{// 遍历链表删除节点,释放内存while (front != nullptr){ListNode* tmp = front;front = front->next;delete tmp;}
}int LinkedListQueue::size()
{return queSize;
}bool LinkedListQueue::isEmpty()
{return size() == 0;
}/*尾插法*/
void LinkedListQueue::push(int num)
{ListNode* node = new ListNode(num);//如果队列为空,则令头、尾节点都指向该节点if (front == nullptr){front = node;rear = node;}else//队列不为空,则将该节点添加到尾节点后{rear->next = node;rear = node;}++queSize;
}int LinkedListQueue::peek()
{if (size() == 0){throw out_of_range("队列为空");}	return front->val;
}//队头出队
int LinkedListQueue::pop()
{//获取队首元素int num = peek();ListNode* tmp = front;front = front->next;//释放内存delete tmp;--queSize;return num;
}vector<int> LinkedListQueue::toVector()
{vector<int> nums;ListNode* node = front;while (node != nullptr){nums.push_back(node->val);node = node->next;}return nums;
}


http://www.ppmy.cn/devtools/97637.html

相关文章

【STM32 Blue Pill编程】-定时器与中断

定时器与中断 文章目录 定时器与中断1、硬件准备及接线2、GPIO配置3、代码实现STM32F103C8 配有四个定时器,分别为 TIM1、TIM2、TIM3 和 TIM4。 它们充当时钟并用于跟踪基于时间的事件。 我们将展示如何使用 HAL 库在 STM32Cube IDE 中对这些定时器进行编程。 本文将涉及如下内…

C++:模拟实现string

前言&#xff1a; 为了更好的理解string底层的原理&#xff0c;我们将模拟实现string类中常用的函数接口。为了与std里的string进行区分&#xff0c;所以用命名空间来封装一个自己的strin类。 string.h #pragma once #define _CRT_SECURE_NO_WARNINGS 1#include<iostream&…

EmguCV学习笔记 VB.Net 4.4 图像形态学

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 教程VB.net版本请访问&#xff1a;EmguCV学习笔记 VB.Net 目录-CSDN博客 教程C#版本请访问&#xff1a;EmguCV学习笔记 C# 目录-CSD…

Java Web —— 第七天(Mybatis案例1)

环境搭建 准备数据库表(dept、emp) -- 部门管理 create table dept(id int unsigned primary key auto_increment comment 主键ID,name varchar(10) not null unique comment 部门名称,create_time datetime not null comment 创建时间,update_time datetime not null commen…

day30(8/16)——ansible

目录 一、回顾 1、mysql和python 1. mysql5.7 2. 可以使用pymysql非交互的管理mysql 2、mycat中间件 1. 独属于mysql主从的负载均衡策略 2.配置写主读从 3. 步骤 3.1 安装jdk 3.2 mycat 3.3 配置 3.4 启动和调试 二、运维自动化&#xff08;ansible&#xff09; 1、任务背…

QT emit关键字

QT的emit关键字 emit 是 Qt 框架中的一个关键字&#xff0c;用于显式地触发信号&#xff08;signals&#xff09;。信号是 Qt 中用于对象间通信的一种机制&#xff0c;通过 emit 关键字&#xff0c;程序员可以在代码中明确地触发信号&#xff0c;从而通知连接的槽&#xff08;…

Vue利用axios请求前携带令牌

请求流程 ① 发起登录请求&#xff0c;拿到后端返回的token&#xff0c;存到 localstorage 中&#xff08; 通过 localStorage.setItem(token,存入的令牌&#xff09;) ② 每一次请求发送之前都进行拦截&#xff0c;给请求添加token&#xff08;通过 localStorage.getItem(tok…

php生成json字符串,python解析json字符串

<?php $nodes []; $_tmp[title] 标题1; $_tmp[titlekey] actt; $_tmp[child] [acww.zip, acww21.zip, tta.zip]; $nodes[] $_tmp;$_tmp2[title] 标题2; $_tmp2[titlekey] kfij; $_tmp2[child] [KL7SHR47.zip, fdgfdg.zip, qweqw.zip]; $nodes[] $_tmp2;// 构建调用…