队列
队列是一种遵循先入先出的线性数据结构,它模拟了排队的现象,新来的不断加入队列的尾部,而位于队列头部的依次离开。
我们将队列的头部成为队首,队列的尾部成为队尾。
将元素添加到队列的操作成为入队,将元素删除队列的操作成为出队
队列的常用操作
push():元素入队,时间复杂度O(1)
pop():元素出队,时间复杂度O(1)
peek()访问队首元素,时间复杂度O(1)
//
// Created by Administrator on 2024/1/10.
//
#include "iostream"
#include "queue"
using namespace std;
int main(){
queue<int> que;
//元素入队
cout<<"元素入队1,2,3"<<endl;
que.push(1);
que.push(2);
que.push(3);
cout<<"访问队首元素:"<<que.front()<<endl;
cout<<"元素出队:"<<endl;
que.pop();
cout<<"访问队首元素:"<<que.front()<<endl;
cout<<"队列长度:"<<que.size()<<endl;
cout<<"判断队列是否为空:"<<que.empty()<<endl;
}
//输出结果
元素入队1,2,3
访问队首元素:1
元素出队:
访问队首元素:2
队列长度:2
判断队列是否为空:0
队列的实现
队列需要在两端进行操作,一端执行入队操作,一端执行出队操作,所以,数组和链表都可以满足
基于链表的实现
我们可以将链表的头节点,尾节点分别作为队列的队头和队尾,规定队尾仅可以添加元素,队首仅可以删除元素
//
// Created by Administrator on 2024/1/10.
//
# include "iostream"
#include "vector"
using namespace std;
struct LinkNode{
int val;
LinkNode *next;
};
class myQueue{
private:
LinkNode *front,*rear;
int queSize;
public:
myQueue() {
front = nullptr;
rear = nullptr;
queSize = 0;
}
//获取队列长度
int size(){
return queSize;
}
//判断队列是否为空
bool empty(){
return queSize==0;
}
//入队
void push(int num){
LinkNode *temp = new LinkNode;
temp->val = num;
if(front == nullptr){
front = temp;
rear = temp;
} else{
rear->next = temp;
rear = temp;
}
queSize++;
}
//访问队首元素
int peek(){
if(queSize == 0){
throw out_of_range("对列为空");
} else{
return front->val;
}
}
//出队
int pop(){
int temp = peek();
LinkNode *node = front;
front = front->next;
delete node;
queSize--;
return temp;
}
/* 将链表转化为 Vector 并返回 */
vector<int> toVector() {
LinkNode *node = front;
vector<int> res(size());
for (int i = 0; i < res.size(); i++) {
res[i] = node->val;
node = node->next;
}
return res;
}
};
int main(){
cout<<"测试基于链表实现队列"<<endl;
cout<<"向队列中添加元素1,2,3"<<endl;
myQueue myque;
myque.push(1);
myque.push(2);
myque.push(3);
cout<<"获取队首元素:"<<myque.peek()<<endl;
cout<<"队列元素个数"<<myque.size()<<endl;
cout<<"队列是否为空?:"<<myque.empty()<<endl;
cout<<"执行出队操作:"<<endl;
myque.pop();
cout<<"获取队首元素:"<<myque.peek()<<endl;
cout<<"队列元素个数"<<myque.size()<<endl;
cout<<"此时队列内的元素:"<<endl;
vector<int> temp = myque.toVector();
for(int i : temp ){
cout<<i<<" ";
}
}
//输出结果
测试基于链表实现队列
向队列中添加元素1,2,3
获取队首元素:1
队列元素个数3
队列是否为空?:0
执行出队操作:
获取队首元素:2
队列元素个数2
此时队列内的元素:
2 3
基于数组的实现
在数组中的首部删除元素的时间复杂度是O(n),这样会是出队的操作效率很低。
我们可以使用一个索引front索引指向队首元素的索引,维护一个变量size来记录队列的大小,那么队尾元素的索引可以通过计算得到rear = front + size;
- 入队操作,只需要将值赋值给rear索引处
- 出队操作,只需要将front+1即可。
- 此时我们就可以发现入队,出队操作都可以在O(1)内完成
//
// Created by Administrator on 2024/1/10.
//
#include "iostream"
#include "vector"
using namespace std;
class myqueue2 {
private:
int front = 0;
int rear = 0;
int *nums;
int quesize = 0;
int queCapacity;
public:
myqueue2(int capacity) {
// 初始化数组
nums = new int[capacity];
queCapacity = capacity;
front = quesize = 0;
};
//获取队列容量
int capacity(){
return queCapacity;
}
//获取队列长度
int size(){
return quesize;
}
//判断队列是否为空
bool empty(){
return quesize == 0;
}
//入队
void push(int num) {
if (quesize == queCapacity) {
cout << "队列已满" << endl;
return;
}
//取余操作是为了索引超出容量时,回到数组的头部
rear = (front + quesize) % queCapacity;//计算尾指针的位置
nums[rear] = num;
quesize++;
}
//获取队首元素
int peek(){
if(empty()){
throw out_of_range("队列为空");
}
return nums[front];
}
//出队
int pop(){
int temp = peek();
front = (front + 1) % queCapacity;
quesize--;
return temp;
}
/* 将数组转化为 Vector 并返回 */
vector<int> toVector() {
// 仅转换有效长度范围内的列表元素
vector<int> arr(quesize);
for (int i = 0, j = front; i < quesize; i++, j++) {
arr[i] = nums[j % queCapacity];
}
return arr;
}
};
int main(){
cout<<"测试基于数组实现的队列"<<endl;
cout<<"将元素1,2,3添加到队列中"<<endl;
myqueue2 myque(10);
myque.push(1);
myque.push(2);
myque.push(3);
cout<<"此时队列中的元素"<<endl;
vector<int> temp = myque.toVector();
for(int i : temp){
cout<<i<<" ";
}
cout<<endl;
cout<<"获取队首元素:"<<myque.peek()<<endl;
cout<<"队列容量:"<<myque.capacity()<<endl;
cout<<"队列长度:"<<myque.size()<<endl;
cout<<"队列是否为空?:"<<myque.empty()<<endl;
cout<<"执行出队操作:"<<endl;
myque.pop();
cout<<"获取队首元素:"<<myque.peek()<<endl;
cout<<"队列容量:"<<myque.capacity()<<endl;
cout<<"队列长度:"<<myque.size()<<endl;
cout<<"此时队列中的元素"<<endl;
vector<int> temp1 = myque.toVector();
for(int i : temp1){
cout<<i<<" ";
}
cout<<endl;
return 0;
}
//数据结果
测试基于数组实现的队列
将元素1,2,3添加到队列中
此时队列中的元素
1 2 3
获取队首元素:1
队列容量:10
队列长度:3
队列是否为空?:0
执行出队操作:
获取队首元素:2
队列容量:10
队列长度:2
此时队列中的元素
2 3
关注微信公众号:IT零壹学府,每日分享自己下学习经验