摘要:
it人员无论是使用哪种高级语言开发东东,想要更高效有层次的开发程序的话都躲不开三件套:数据结构,算法和设计模式。数据结构是相互之间存在一种或多种特定关系的数据元素的集合,即带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系,分为逻辑结构和存储结构。
此系列专注讲解数据结构数组、链表、队列、栈、树、哈希表、图,通过介绍概念以及提及一些可能适用的场景,并以C++代码简易实现,多方面认识数据结构,最后为避免重复造轮子会浅提对应的STL容器。本文介绍的是队Queue。
(开发环境:VScode,C++17)
关键词
: C++,数据结构,队列,Queue
声明:
本文作者原创,转载请附上文章出处与本文链接。
文章目录
- 摘要:
- 正文:
- 介绍:
- 特性:
- 应用:
- 代码实现:
- 对应STL:
- 推荐阅读
正文:
介绍:
队列(Queue)是一种常见的数据结构,它遵循先入先出(FIFO,First In First Out)的原则。队列中的元素按照它们进入队列的顺序排列,并且只有队首的元素可以被删除,队尾的元素可以被添加。
队列也有两种存储表示方法:顺序存储(用数组实现)和链式存储(用链表实现),顺序存储常见的就是环形队列,初始化时必须指定队列容量大小;普通队列则基于链表。
特性:
-
先进先出:队列的基本操作是遵循FIFO(先进先出)原则的。这意味着最早添加到队列中的元素将是最早被移除的。这种特性使得队列在处理需要按顺序处理的元素时非常有用,比如任务调度、打印作业等。
-
受限的访问:队列只允许在两端进行操作。在队列的一端(称为“队尾”或“后端”)添加元素,而在另一端(称为“队头”或“前端”)移除元素。这种特性确保了队列中的元素按照它们被添加的顺序进行处理。
应用:
队列在多种场景中都有应用,包括:
- 任务调度:在计算机系统中,多个任务可能同时请求CPU资源。使用队列可以确保任务按照它们到达的顺序得到处理。
- 打印机作业队列:当一个用户提交一个打印作业时,它会被添加到打印队列中。打印机按照作业进入队列的顺序打印它们。
- 网络数据包处理:在网络通信中,接收到的数据包需要按照它们到达的顺序进行处理。队列可以帮助管理这些数据包,确保它们按照正确的顺序被处理。
- 图形界面事件处理:在图形用户界面(GUI)中,用户事件(如鼠标点击或键盘输入)被添加到事件队列中。事件处理程序按照事件进入队列的顺序处理它们。
代码实现:
#cqueue.h
#ifndef CQUEUE_H
#define CQUEUE_H
#include <iostream>
using namespace std;// 队链节点
template<class T>
class CQueueNode
{
public:CQueueNode(T t) :data(t), next(NULL) {}~CQueueNode() { next = NULL; }CQueueNode(const CQueueNode& node){if (this == &node){return;}*this = node;}CQueueNode& operator=(const CQueueNode& node){if (this == &node){return *this;}this->data = node.data;this->next = node.next;return *this;}public:T data;CQueueNode *next;
};// 普通队列实现,基于链表
template<class T>
class CQueue
{
public:CQueue() :head(NULL), tail(NULL), node(NULL), m_iSize(0) {}~CQueue(){delete head;head = NULL;delete tail;tail = NULL;delete node;node = NULL;}int size(); // 获取队内成员个数 bool empty(); // 判断是否为空队列void push(T t); // 队尾入队T pop(); // 队首出队T front(); // 返回队首T back(); // 返回队尾void traverse(); // 打印整个队列private:CQueueNode<T>* head;CQueueNode<T>* tail;CQueueNode<T>* node;int m_iSize;
};template<class T>
int CQueue<T>::size()
{return m_iSize;
}template<class T>
bool CQueue<T>::empty()
{return 0 == m_iSize;
}template<class T>
void CQueue<T>::push(T t)
{node = new CQueueNode<T>(t);if (head == NULL){head = tail = node;}else{tail->next = node;tail = node;}m_iSize++;
}template<class T>
T CQueue<T>::pop()
{if (empty()){throw "empty queue.";}node = head;head = head->next;m_iSize--;return node->data;
}template<class T>
T CQueue<T>::front()
{if (empty()){throw "empty queue.";}return head->data;
}template<class T>
T CQueue<T>::back()
{if (empty()){throw "empty queue.";}return tail->data;
}template<class T>
void CQueue<T>::traverse()
{CQueueNode<T> *node = head;while (node != NULL){cout << node->data << " ";node = node->next;}cout << endl;
}#endif // !CQUEUE_H
#cqueue.cpp
#include "cqueue.h"
using namespace std;int main(int argc, char**argv)
{CQueue<char> queue;queue.push('h');queue.push('e');queue.push('l');queue.push('l');queue.push('o');queue.push(' ');queue.push('w');queue.push('o');queue.push('r');queue.push('l');queue.push('d');queue.traverse();cout << queue.front() << endl;cout << queue.back() << endl;char c = queue.pop();cout << c << endl;queue.traverse();return 0;
}
对应STL:
-
queue:
普通队列。其原理是先进先出(FIFO),只有队头和队尾可以被访问,故不可有遍历行为,默认也为deque双端队列
-
deque:
双端队列。支持头插、删,尾插、删,随机访问较vector容器来说慢,但对于首尾的数据操作比较方便
推荐阅读
C/C++专栏:https://blog.csdn.net/weixin_45068267/category_12268204.html
(内含其它数据结构及对应STL容器使用)