数据结构与算法之队列
1.队列(Queue)的基本概念
队列是只允许在表的一端进行插入,另一端进行删除的线性表。允许插入的一端叫队尾(rear),允许删除的一端叫队头(front)。不含元素的列队称为空队列。队列的特点是先进先出(First in First Out)。
2.队列的存储结构
-
队列的顺序存储结构称为顺序队列(选择环形队列模型)。
它由一个存放队列元素的一维数组,以及分别指示队头和队尾的“指针”组成(并不是指针变量,而是int型)。约定队尾指针指示队尾元素在一维数组中的当前位置,队头指针指示队头元素在一维数组中当前位置的前一个位置。与栈的顺序存储一样,队列的顺序存储也存在溢出等问题。
-
队列的链式存储结构,简称链队列。
它实际上是一个同时带有头指针和尾指针的单链表,头指针指向头结点,尾指针指向尾结点。
3.队列运算
队列的常见操作有创建、销毁、清空、判满、判空、队长、入队、出队遍历等基本运算。以下分别列出基于C和C++实现的队列源代码:
以下为基于c++的实现队列的源代码:
MyQueue.h
//环形队列c实现
#ifndef MYQUEUE_H
#define MYQUEUE_H
class MyQueue
{
public:
MyQueue(int queueCapacity);//创建队列
virtual ~MyQueue(); //销毁队列
void ClearQueue(); //清空队列
bool QueueFull() const; //判满队列
bool QueueEmpty() const; //判空队列
int QueueLenth() const; //队列长度
bool EnQueue(int element); //入队
bool DeQueue(int &element);//出队
void QueueTraverse(); //遍历队列
private:
int *m_pQueue; //队列数组指针
int m_iQueueLen; //队列的元素个数
int m_iQueueCapacity; //队列的数组容量
int m_iFront; //队头
int m_iRear; //队尾
};
#endif
MyQueue.cpp
#include<iostream>
#include<stdlib.h>
#include<string>
#include"Myqueue.h"
using namespace std;
//创建队列
MyQueue::MyQueue(int queueCapacity)
{
m_iQueueCapacity = queueCapacity;
m_pQueue = new int[queueCapacity];
ClearQueue();
}
//销毁队列
MyQueue::~MyQueue()
{
delete[]m_pQueue;
m_pQueue = NULL;
}
//清空队列
void MyQueue::ClearQueue()
{
m_iFront = 0;
m_iRear = 0;
m_iQueueLen = 0;
}
//判断是否为满
bool MyQueue::QueueFull() const
{
return m_iQueueCapacity == m_iQueueLen ? true : false;
}
//判空队列
bool MyQueue::QueueEmpty() const
{
return m_iQueueLen == 0 ? true : false;
}
//队列长度
int MyQueue::QueueLenth() const
{
return m_iQueueLen;
}
//入队
bool MyQueue::EnQueue(int element)
{
if (QueueFull())
{
cout << "队列已满!\n";
return false;
}
else
{
*(m_pQueue + m_iRear) = element;
m_iRear++;
m_iRear = m_iRear % m_iQueueCapacity;//利用取余%运算,可以实现队头、队尾指针在循环意义上的+1操作
m_iQueueLen++;
return true;
}
}
//出队
bool MyQueue::DeQueue(int &element)
{
if (QueueEmpty())
{
cout << "队列为空!\n";
return false;
}
else
{
element = *(m_pQueue + m_iFront);
m_iFront++;
m_iFront = m_iFront % m_iQueueCapacity;
m_iQueueLen--;
return true;
}
}
//遍历
void MyQueue::QueueTraverse()
{
for (int i = m_iFront; i < m_iQueueLen + m_iFront; i++)//注意i的初值和循环条件
{
cout << *(m_pQueue + i % m_iQueueCapacity) << endl;//注意此处对i的处理
}
}
main.cpp
#include<iostream>
#include<stdlib.h>
#include<string>
#include"Myqueue.h"
using namespace std;
int main(void)
{
MyQueue *p = new MyQueue(4);
/*p->EnQueue(10); //测试操作
p->EnQueue(11);
p->EnQueue(12);
p->EnQueue(13);
p->EnQueue(14);
p->QueueTraverse();
cout << endl;
int e;
p->DeQueue(e);
cout << e << endl;
p->DeQueue(e);
cout << e << endl;
p->QueueTraverse();
p->ClearQueue();
p->QueueTraverse();
p->EnQueue(90);
p->QueueTraverse();*/
delete p;
p = NULL;
system("pause");
return 0;
}
以下为基于c的实现队列的源代码:
顺序队列
//顺序队列
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 5
typedef int elemtype;
typedef struct
{
elemtype elem[MAXSIZE];
int front, rear;
}cqueuetp;
int main(void)
{
void InitQueue(cqueuetp *sq); //函数声明
int QueueEmpty(cqueuetp *sq);
int Size(cqueuetp *sq);
elemtype Head(cqueuetp *sq);
void EnQueue(cqueuetp *sq, elemtype x);
elemtype DelQueue(cqueuetp *sq);
cqueuetp *sq; //初始化操作
sq = (cqueuetp *)malloc(sizeof(cqueuetp));
InitQueue(sq);
int i = 0;
while (i != MAXSIZE)
{
EnQueue(sq, i);
i++;
}
i = 1;
while (sq->front != sq->rear)
{
printf("这是第%d个进去的数:", i);
printf("%d\n", DelQueue(sq));
i++;
}
return 0;
}
//初始化
void InitQueue(cqueuetp *sq)
{
sq->front = 0;
sq->rear = 0;
}
//判断队列是否为空
int QueueEmpty(cqueuetp *sq)
{
if (sq->front == sq->rear)
return 1;
else
return 0;
}
//求队列的长度
int Size(cqueuetp *sq)
{
return ((MAXSIZE + sq->rear - sq->front) % MAXSIZE);
}
//读取头元素操作
elemtype Head(cqueuetp *sq)
{
if (sq->front == sq->rear)
return NULL;
else
return (sq->elem[(sq->front + 1)%MAXSIZE]);
}
//入队操作
void EnQueue(cqueuetp *sq, elemtype x)
{
if ((sq->rear + 1) % MAXSIZE == sq->front)
printf("Overflow!\n");
else
{
sq->rear = (sq->rear + 1) % MAXSIZE;
sq->elem[sq->rear] = x;
}
}
//出队操作
elemtype DelQueue(cqueuetp *sq)
{
if (sq->front == sq->rear)
return NULL;
else
{
sq->front = (sq->front + 1) % MAXSIZE;
return (sq->elem[sq->front]);
}
}
链队列
//队列的链式存储——链队列
#include<stdio.h>
#include<stdlib.h>
typedef int elemtype;
typedef struct NODETYPE //链队列类型定义
{
elemtype data;
struct NODETYPE *next;
}nodetype;
typedef struct
{
nodetype *front;
nodetype *rear;
}lqueuetp;
int main(void)
{
void InitQueue(lqueuetp *lq);
int QueueEmpty(lqueuetp *lq);
void EnQueue(lqueuetp *lq, elemtype x);
elemtype DelQueue(lqueuetp *lq);
lqueuetp *lq;
lq = (lqueuetp *)malloc(sizeof(lqueuetp));
InitQueue(lq);
int i = 0;
while (i != 5)
{
EnQueue(lq, i);
i++;
}
i = 1;
while (lq->front != lq->rear)
{
printf("这是第%d个进去的数:", i);
printf("%d\n", DelQueue(lq));
i++;
}
return 0;
}
//初始化
void InitQueue(lqueuetp *lq)
{
lq->front = (nodetype *)malloc(sizeof(nodetype));
lq->front->next = NULL;
lq->rear = lq->front;
}
//判断队空操作
int QueueEmpty(lqueuetp *lq)
{
if (lq->front == lq->rear)
return 1;
else
return 0;
}
//入队
void EnQueue(lqueuetp *lq, elemtype x)
{
nodetype *s;
s = (nodetype *)malloc(sizeof(nodetype));
s->data = x;
s->next = NULL;
lq->rear->next = s;
lq->rear = s;
}
//出队
elemtype DelQueue(lqueuetp *lq)
{
elemtype x;
nodetype *q;
if (lq->front == lq->rear)
{
return NULL;
}
else
{
q = lq->front->next;
lq->front->next = q->next;
if (q->next == NULL)
lq->rear = lq->front;
x = q->data;
free(q);
return x;
}
}