提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
队列
队列: 是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一一样,队列是一种操作受限的线性表。进行插入操作的端称队尾,进行插入操作的端称为队尾,进行删除操作的端称为队头;
队列的特点: 先进先出;
队列中有两个值,一个是front记录队头的位置,另一个是rear记录队尾的位置。
在实际应用时,由于数组队列的缺点是由于一端插入一端删除,当不断从头部删除数据,头部会大量留有空闲内存,无法插入,造成空间流失,这种属于假溢出的情况。但如果将队头指针在每次删除之后往前移动一个位置,这是一个时间复杂度为O(n)的操作。因此,通常将队列设计为循环队列来克服上述问题。
循环队列: 可以看作是一个环形结构。有一个maxsize表示数组的长度。当队列未满,并且队头已经到达了maxsize的位置,再次插入数据的时候,队头则从0位置开始插入。
在设计的时候,一般要注意以下几点:
(1)队列初始化时,front和rear值都为零。
(2)当队列不为空时,front指向队列的第一个元素,rear指向队列最后一个元素的下一个位置。
(3)当队列为空时,front与rear的值相等,但不一定为零。
循环队列满的时候会满足这个计算公式 : (rear+1)%maxsize=front
计算循环队列长度 : (rear-front+maxsize)%maxsize
c++的代码实现
1.数组实现
首先定义一个Queue类
class Queue
{
private:
ElemType *_data;
int _head;
int _tail;
bool IsFull();
bool IsEmpty();
public:
Queue();
Queue(const Queue &src);
Queue& operator= (const Queue& src);
~Queue();
bool Push(ElemType val);
bool Pop();
ElemType GetQue();
void show();
};
判空和判满的实现
bool Queue::IsFull()
{
assert(this != NULL);
if ((_tail + 1) % SIZE == _head)
{
return true;
}
return false;
}
bool Queue::IsEmpty()
{
assert(this != NULL);
if (_head == _tail)
{
return true;
}
return false;
}
出队列、入队列、获得队头的数据的功能实现
bool Queue::Push(ElemType val)
{
assert(this != NULL);
if (IsFull())
{
return false;
}
_data[_tail++] = val;
_tail %= SIZE;
return true;
}
bool Queue::Pop()
{
assert(this != NULL && _data != NULL);
if (IsEmpty())
{
return false;
}
_head++;
_head %= SIZE;
return true;
}
ElemType Queue::GetQue()
{
assert(this != NULL);
if (IsEmpty())
{
return 0;
}
return _data[_head];
}
2.链表实现
2.1 单向链表实现
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
struct Node
{
int val;
Node* next;
Node(int v) : val(v),next(nullptr)
{
}
};
class Queue
{
int size;
Node* head;
Node* back;
public:
Queue() : size(0),head(nullptr),back(nullptr){}
bool empty(){ return 0 == size;}
Node* front()
{
return head;
}
Node* push_back(int v)
{
if(0 == size)
{
head->next = head = back = new Node(v);
}
else if(1 == size)
{
head->next = back = new Node(v);
}
else
{
}
}
};
2.2 双向链表实现
#include <iostream>
using namespace std;
typedef struct node
{
int data;
node* prev;
node* next;
}Node;
typedef struct queue
{
Node* front;
Node* rear;
}LinkDQueue;
void En_DQueuelist(LinkDQueue* q,int e); //入队函数
int De_DQueuelist(LinkDQueue* q); //出队函数
void Print_DQueuelist(LinkDQueue* q); //打印队列
int Getlength_DQueuelist(LinkDQueue* q); //计算双端队列长度函数
//创建双端队列函数
LinkDQueue* Creat_DQueuelist()
{
LinkDQueue* queue = new LinkDQueue;
queue->front = queue->rear = new Node;
queue->front->data = 0;
queue->front->prev = NULL;
queue->front->next = NULL;
queue->rear->next = NULL;
int length = 0;
int number = 0;
cout << "请输入双端队列长度:";
cin >> length;
if (!length)
{
return queue;
}
cout << "请输入双端队列数据:";
for (int i = 0; i < length; i++) //端口2创建双端队列
{
Node* pnew = new Node;
if (!pnew)
cout << "内存分配失败!" << endl;
cin >> number;
pnew->data = number;
pnew->next = NULL;
queue->rear->next = pnew;
pnew->prev = queue->rear;
queue->rear = pnew;
}
return queue;
}
void En_DQueuelist(LinkDQueue* q, int e) {
int n = 0;
Node* tmp = new Node;
tmp->data = e;
cout << "请输入顺序入队端口:";
cin >> n;
if (q->front == q->rear) {
q->rear->next = tmp;
tmp->prev = q->rear;
tmp->next = NULL;
q->rear = tmp;
return;
}
switch (n) {
case 1:
tmp->next = q->front->next;
q->front->next->prev = tmp;
q->front->next = tmp;
tmp->prev = q->front;
break;
case 2:
tmp->next = NULL;
q->rear->next = tmp;
tmp->prev = q->rear;
q->rear = tmp;
break;
}
}
int De_DQueuelist(LinkDQueue* q) {
int data = INT_MAX;
if (!q || q->front == q->rear) {
cout << "队列为空!" << endl;
return data;
}
int n = 0;
Node* tmp = NULL;
cout << "请输入顺序出队端口:";
cin >> n;
switch (n) {
case 1:
tmp = q->front->next;
data = tmp->data;
q->front->next = tmp->next;
if (q->rear == tmp) {
q->rear = q->front;
} else {
tmp->next->prev = q->front;
}
delete tmp;
return data;
case 2:
tmp = q->rear;
data = tmp->data;
tmp->prev->next = NULL;
q->rear = tmp->prev;
// tmp->prev = NULL;
delete tmp;
return data;
}
}
void Print_DQueuelist(LinkDQueue* q) {
int n = 0;
Node * tmp = NULL;
cout << "请输入顺序打印端口:";
cin >> n;
switch (n) {
case 1:
tmp = q->front->next;
while (tmp) {
cout << tmp->data << ' ';
tmp = tmp->next;
}
break;
case 2:
tmp = q->rear;
while (tmp != q->front) {
cout << tmp->data << ' ';
tmp = tmp->prev;
}
break;
}
}
int Getlength_DQueuelist(LinkDQueue* q) {
int length = 0;
Node* tmp = q->front->next;
while (tmp) {
length++;
tmp = tmp->next;
}
return length;
}
int main()
{
LinkDQueue* queue = Creat_DQueuelist();
Print_DQueuelist(queue);
cout << "length: " << Getlength_DQueuelist(queue) << endl;
En_DQueuelist(queue, 4);
Print_DQueuelist(queue);
cout << "length: " << Getlength_DQueuelist(queue) << endl;
int data = De_DQueuelist(queue);
if (data != INT_MAX) {
cout << "删除元素:" << data << endl;
}
Print_DQueuelist(queue);
return 0;
}