队列(Queue)
只允许在一端进行插入操作,另一端进行删除操作的线性表。
特点:FIFO(First In First Out)
读完数据结构队列模型后,按照抽象数据模型实现一部分队列的功能,代码如下
1 顺序存储结构–顺序队列
//2021/03/10H:\图解数据结构算法\队列\队列.vcxproj
#include <iostream>
#include <time.h>
using namespace std;;
typedef int QElemType;
typedef bool Status;
#define MAXSIZE 100
class SqQueue
{
public:
SqQueue()
{
//初始化
my_front= 0;
my_rear = 0;
my_length = 0;
}
//入队操作
Status EnQueue(QElemType e)
{
//先判断队列是否满了
if ( (my_rear + 1)%MAXSIZE == my_front)
{
return false;
}
data[my_rear] = e; //将元素e赋值给队尾指针指向的位置
my_rear = (my_rear + 1) % MAXSIZE; //队尾指针后移,若超出队列长度,则移到队首
return true;
}
//出队操作
Status OutQueue(QElemType *e)
{
//先判断队列是否为空
if (my_rear == my_front)
{
return false;
}
*e = data[my_front];
my_front = (my_front + 1) % MAXSIZE; //队头指针后移,若超出队列长度,则移到队首
return true;
}
//返回长度
int GetLength()
{
return (my_rear - my_front + MAXSIZE) % MAXSIZE;
}
private:
QElemType data[MAXSIZE]; //数据元素
int my_front; //头指针
int my_rear; //尾指针
int my_length; //队列长度
};
//测试代码
int main()
{
SqQueue sq;
srand(time(0)); //随机数种子
for (int i = 0; i < 4; i++)
{
int num = rand() % 100 + 1;
cout << "正在进行入队操作:" << num << ",已入队!" << endl;
sq.EnQueue(num);
cout << "此时队列数目:" << sq.GetLength() << endl;
cout << "--" << endl;
}
for (int i = 0; i < 5; i++)
{
int num;
bool ref;
ref = sq.OutQueue(&num);
if (ref == true)
{
cout << "正在进行出队操作:" << num << ",已出队!" << endl;
}
else
{
cout << "队列已无元素!出队ERROR" << endl;
}
cout << "此时队列数目:" << sq.GetLength() << endl;
cout << "--" << endl;
}
cout << "hello world!" << endl;
system("pause");
return 0;
}
输出
使用相同的测试代码
随机入队列4个元素,出队列5个元素
2 链式存储结构–链队列
//2021/03/11H:\图解数据结构算法\队列\队列.vcxproj
#include <iostream>
#include <time.h>
using namespace std;
typedef int QElemType;
typedef bool Status;
//队列的单个结点,具有数据域和指针域
typedef struct QNode
{
QElemType data; //数据域
struct QNode* next; //指针域
}QNode, *QNodePtr;
//链队列
class LinkQueue
{
public:
LinkQueue()
{
QNodePtr T = (QNodePtr)malloc(sizeof(QNode)); //需要一个头结点
T->next = NULL;
my_front = T; //指向头结点
my_rear = T; //指向头结点
my_length = 0; //长度置为0
}
~LinkQueue()
{
QNodePtr tmp = NULL;
while (my_front) //从头结点遍历,依次释放内存
{
tmp = my_front;
my_front = my_front->next;
free(tmp);
my_length = 0;
}
}
//入队列
Status EnQueue(QElemType e)
{
QNodePtr s = (QNodePtr)malloc(sizeof(QNode));
if (!s)
{
exit(OVERFLOW); //储存分配失败
}
s->data = e; //给新结点赋值
s->next = NULL; //加在队尾,所以next为NULL
this->my_rear->next = s; //队尾指针链接s
this->my_rear = s; //队尾指针重新指向s
my_length++; //长度加1
return true;
}
//出队列
Status OutQueue(QElemType* e)
{
//先判断是否有元素在队列中
if (my_front == my_rear || my_length == 0)
{
return false;
}
*e = this->my_front->next->data;
QNodePtr tmp = my_front->next; //tmp临时指向队头
my_front->next = tmp->next; //队头指针指向下一位置
//如果队头就是队尾
if (my_rear == tmp)
{
my_rear = my_front; //都指向头结点
}
free(tmp); //释放内存
my_length--; //长度减一
return true;
}
//获取队列的长度
int GetLength()
{
//遍历链表?
int count = 0;
QNodePtr tmp = my_front->next; //因为有头结点,从第一个结点开始
while (tmp)
{
tmp = tmp->next;
count++;
}
my_length = count;
return count;
}
private:
QNodePtr my_front, my_rear; //队列具有头指针和尾指针
int my_length; //队列当前长度
};
//测试代码,与顺序队列测试代码相同
int main()
{
LinkQueue sq;
srand(time(0));
for (int i = 0; i < 4; i++)
{
int num = rand() % 100 + 1;
cout << "正在进行入队操作:" << num << ",已入队!" << endl;
sq.EnQueue(num);
cout << "此时队列数目:" << sq.GetLength() << endl;
cout << "--" << endl;
}
for (int i = 0; i < 5; i++)
{
int num;
bool ref;
ref = sq.OutQueue(&num);
if (ref == true)
{
cout << "正在进行出队操作:" << num << ",已出队!" << endl;
}
else
{
cout << "队列已无元素!出队ERROR" << endl;
}
cout << "此时队列数目:" << sq.GetLength() << endl;
cout << "--" << endl;
}
cout << "hello world!" << endl;
system("pause");
return 0;
}
输出
使用相同的测试代码
随机入队列4个元素,出队列5个元素