目录
简介:
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。
图文:
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。队列是一种先进先出(First in First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。假设队列是q=(a1,a2,…,an),那么a1就是队头元素,而an是队尾元素。这样我们就可以删除时,总是从a1开始,而插入时,列在最后。这也比较符合我们通常生活中的习惯,排在第一个的优先出列,最后来的当然在队伍的最后。
出入队列:
定义:
#include "stdio.h"
#define MAXSIZE 5 //最大容量是5个元素
struct queue //队列
{
int a[MAXSIZE]; //队列元素
int front; //队头
int rear; //队尾
};
入队操作:
步骤一:判断是否溢出,若溢出给出提示结束程序,否则跳到步骤二
步骤二:输入入队的元素
步骤三:将元素存于队尾处
步骤四:队尾下标自增
void enqueue(struct queue *q)
{
int e;
if(q->rear<MAXSIZE-1)
{
printf("请输入入队的元素:");
scanf("%d",&e);
q->a[q->rear]=e;
q->rear++;
printf("入队成功\n");
}
else
{
printf("溢出\n");
}
}
出队操作:
步骤一:判断是有元素,若无元素则给出提示结束程序,否则跳到步骤二
步骤二:用e接收出队的元素
步骤三:
步骤四:队尾下标自增
void dequeue(struct queue *q)
{
int e;
if(q->front==q->rear)
{
printf("队空,没有元素\n");
}
else
{
e=q->a[q->front];
q->front++;
printf("出队的元素是%d\n",e);
}
}
循环队列:
为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。
第一次: 进队
第一次: 出队
第二次: 进队
(1)
(2)
(3)
(4)
代码:
#include <stdio.h>
#include <assert.h>
#include <Windows.h>
#include <iostream>
#include <iomanip>
using namespace std;
#define MAXSIZE 5 //循环队列的最大容量
typedef int DataType; //循环队列中元素类型
typedef struct Queue
{
DataType queue[MAXSIZE];
int front;
int rear;
}SeqQueue;
//队列初始化, 将循环队列初始化为空队列
void InitQueue(SeqQueue* SQ)
{
if (!SQ) return;
SQ->front = 0;
SQ->rear = 0;
}
//判断队列为空
int IsEmpty(SeqQueue* SQ)
{
if (!SQ) return 0;
if (SQ->front == SQ->rear)
{
return 1;
}
return 0;
}
//判断循环队列是否为满
int IsFull(SeqQueue* SQ)
{
if (!SQ) return 0;
if ((SQ->rear + 1) % MAXSIZE == SQ->front)
{
return 1;
}
return 0;
}
//入队, 将元素data插入到循环队列SQ中
int EnterQueue(SeqQueue* SQ, DataType data)
{
if (!SQ) return 0;
if (IsFull(SQ))
{
cout << "无法插入元素: " << data << ", 队列已满" << endl;
return 0;
}
SQ->queue[SQ->rear] = data; //在队尾插入元素data
SQ->rear = (SQ->rear + 1) % MAXSIZE; //队尾指针循环后移一位
return 1;
}
//出队, 将队列中队头的元素data出队, 出队后 队头指针 front 后移一位
int DeleteQueeue(SeqQueue* SQ, DataType* data)
{
if (!SQ || IsEmpty(SQ))
{
cout << "循环队列为空! " << endl;
return 0;
}
*data = SQ->queue[SQ->front];
SQ->front = (SQ->front + 1) % MAXSIZE;
return 1;
}
//打印队列中的各个元素
void PrintQueue(SeqQueue* SQ)
{
if (!SQ) return;
int i = SQ->front;
while (i != SQ->rear)
{
cout << setw(4) << SQ->queue[i];
i = (i + 1) % MAXSIZE;
}
cout << endl;
}
//获取队首元素, 不出队
int GetHeand(SeqQueue* SQ, DataType* data)
{
if (!SQ || IsEmpty(SQ))
{
cout << "队列为空" << endl;
}
return *data = SQ->queue[SQ->front];
}
//获取队列中元素的个数
int getLength(SeqQueue* SQ)
{
if (!SQ) return 0;
return ((SQ->rear) - SQ->front + MAXSIZE) % MAXSIZE;
}
int main()
{
SeqQueue* SQ = new SeqQueue;
DataType data = -1;
//初始化队列
InitQueue(SQ);
//入队
for (int i = 0; i < 7; i++)
{
EnterQueue(SQ, i);
}
//打印队列中的元素
printf("队列中的元素(总共 %d 个) \n", getLength(SQ));
PrintQueue(SQ);
cout << endl;
//出队
for (int i = 0; i < 4; i++)
{
if (DeleteQueeue(SQ, &data))
{
cout << "出队的元素是: " << data << endl;
}
else
{
cout << "出队失败" << endl;
}
}
//打印队列中的元素
printf("出队 4 个元素后, 队列中剩下的元素个数为 %d 个: ", getLength(SQ));
PrintQueue(SQ);
cout << endl;
//入队 4 个
for (int i = 0; i < 4; i++)
{
EnterQueue(SQ, i + 10);
}
printf("\n入队 4 个元素后, 队列中剩下的元素个数为 %d 个: \n", getLength(SQ));
PrintQueue(SQ);
system("pause");
return 0;
}
顺序队列:
队列的顺序储存结构:用数组存储队列,为了避免当只有一个元素时,队头和队尾重合使得处理变得麻烦,所以引入两个指针:front 指针指向队头元素,rear 指针指向队尾元素的下一个位置,当 front=rear 时,为空队列
顺序队列的结构代码如下:
#include <stdio.h>
#define MAX_LEN 100 //规定数组的长度
//实现入队操作
int enQueue(int* a, int rear, int data) {
//如果 rear 超出数组下标范围,队列将无法继续添加元素
if (rear == MAX_LEN) {
printf("队列已满,添加元素失败\n");
return rear;
}
a[rear] = data;
rear++;
return rear;
}
//实现出队操作
int deQueue(int* a, int top, int rear) {
//如果 top==rear,表示队列为空
if (top == rear) {
printf("队列已空,出队执行失败\n");
return top;
}
printf("出队元素:%d\n", a[top]);
top++;
return top;
}
int main() {
int a[MAX_LEN];
int top, rear;
//设置队头指针和队尾指针,当队列中没有元素时,队头和队尾指向同一块地址
top = rear = 0;
//入队
rear = enQueue(a, rear, 1);
rear = enQueue(a, rear, 2);
rear = enQueue(a, rear, 3);
rear = enQueue(a, rear, 4);
//出队
top = deQueue(a, top, rear);
top = deQueue(a, top, rear);
top = deQueue(a, top, rear);
top = deQueue(a, top, rear);
top = deQueue(a, top, rear);
return 0;
}