前言
- 关于
假溢出
和循环队列
队列的特性是先进先出,后入后出(FIFO),我们在进行入队列和出队列操作时,在队头进行删除元素,在队尾插入元素;假设我们定义一个空间大小MAXSIZE为5的队列:
当队头元素a出列时,队列空间中就会出现一个空单元,但是如果再来新的元素却无法入队列,因为e后面没有空单元了,队列未溢出却无法入队,这种现象叫假溢出
循环队列的出现就是为了解决假溢出问题,循环队列的最后一个单元的后继单元为第一个单元。
循环队列溢出的条件为:(rear + 1) % MAXSIZE = front
队列的部分ADT
- InitQueue():初始化一个空队列
- EnterQueue():入队列
- DeleteQueue():出队列
- CreateQueue():建立一个队列
- DisposeQueue():销毁一个队列
- IsFull():判断是否为溢出
- IsEmpty():判断是否为空队列
链队列
链队列的入队和出队操作不涉及到队列的溢出情况,这里就没有IsFull操作,只有当设备的内存溢出是队列才会溢出。
存储结构
全部代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct QueueNode
{
int data; //数据域
struct QueueNode * next; //指针域
}LinkQueueNode;
typedef struct
{
LinkQueueNode * front;
LinkQueueNode * rear;
}LinkQueue;
//初始化队列,即置空队列
void InitQueue(LinkQueue* Q)
{
Q->front = (LinkQueueNode *)malloc(sizeof(LinkQueueNode));
if(Q->front == NULL)
printf("初始化失败!!\n");
else
{
Q->front->next = NULL;
Q->rear = Q->front;
printf("初始化成功!!\n");
}
}
//判断是否为空队列
bool IsEmpty(LinkQueue* Q)
{
if(Q->front == Q->rear) return true;
else return false;
}
//入队列
void EnterQueue(LinkQueue* Q,int x)
{
LinkQueueNode* NewNode;
NewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
if(NewNode == NULL)
printf("队列溢出!!\n");
else
{
NewNode->data = x;
NewNode->next = NULL;
Q->rear->next = NewNode;
Q->rear = NewNode;
printf("入队成功!!\n");
}
}
//出队列
void DeleteQueue(LinkQueue* Q)
{
if(IsEmpty(Q))
printf("队列为空,无法进行出队列操作!!\n");
else
{
int x;
LinkQueueNode * Node;
Node = Q->front->next;
Q->front->next = Node->next;
if(Q->rear == Node)
Q->rear = Q->front;
x = Node->data;
free(Node);
printf("队列元素%d出队成功!!\n",x);
}
}
//打印队列
void PrintQueue(LinkQueue* Q)
{
LinkQueueNode * head;
head = Q->front;
if(IsEmpty(Q))
printf("队列为空,无法打印!!\n");
else
{
printf("打印结果:");
while(head->next != NULL)
{
head = head->next;
printf("%d\t",head->data);
}
printf("\n打印成功!!\n");
}
}
//创建队列
void CreateQueue(LinkQueue* Q)
{
//1.初始化一个队列
InitQueue(Q);
//2.循环入队
int x; //入队元素
char c; //结束标志
while(1)
{
scanf("%d",&x);
EnterQueue(Q, x);
c = getchar();
if(c == '\n')
break;
}
//3.打印队列
PrintQueue(Q);
//4.创建成功
printf("创建成功!!\n\n");
}
//销毁队列
void DisposeQueue(LinkQueue* Q)
{
while(Q->front != Q->rear)
DeleteQueue(Q);
printf("队列销毁成功!!\n");
}
int main()
{
//测试
LinkQueue L;
CreateQueue(&L);
EnterQueue(&L,5);
PrintQueue(&L);
DeleteQueue(&L);
PrintQueue(&L);
DisposeQueue(&L);
return 0;
}
队列的顺序表示
队列的顺序表示就是通过数组来存储队列,但是会出现假溢出现象,所以我们直接用循环队列来实现队列的顺序存储。
全部代码
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 30
typedef struct
{
int element[MAXSIZE];
int front;
int rear;
}SeqQueue;
//初始化队列
void InitQueue(SeqQueue* Q)
{
Q->front = Q->rear = 0;
}
//判断是否溢出
bool IsFull(SeqQueue* Q)
{
if((Q->rear+1) % MAXSIZE == Q->front)
return true;
else
return false;
}
//判断队列是否为空
bool IsEmpty(SeqQueue* Q)
{
if(Q->rear == Q->front)
return true;
else
return false;
}
//入队操作
void EnterQueue(SeqQueue* Q, int x)
{
if(IsFull(Q))
printf("队列已满,无法入队!!\n\n");
else
{
Q->element[Q->rear] = x;
Q->rear = (Q->rear+1) % MAXSIZE;
printf("%d入队成功!!\n",x);
}
}
//出队操作
void DeleteQueue(SeqQueue* Q)
{
if(IsEmpty(Q))
printf("队列为空,出队失败!!\n");
else
{
printf("%d出队!\n",Q->element[Q->front]);
Q->front = (Q->front+1) % MAXSIZE;
}
}
//创建队列
SeqQueue* CreateQueue()
{
SeqQueue* Q;
Q = (SeqQueue*)malloc(sizeof(SeqQueue));
InitQueue(Q);
int x; //入队元素
char c; //结束标志
while(1)
{
scanf("%d",&x);
EnterQueue(Q, x);
c = getchar();
if(c == '\n')
break;
}
printf("创建成功\n");
return Q;
}
//销毁队列
void DisposeQueue(SeqQueue* Q)
{
free(Q);
Q = NULL;
}
//打印队列
void PrintQueue(SeqQueue* Q)
{
if(IsEmpty(Q))
printf("队列为空,打印失败!!\n");
else
{
printf("打印结果:");
int i = Q->front;
while(1)
{
printf("%d\t",Q->element[i]);
i = (i + 1) % MAXSIZE;
if(i == Q->rear)
break;
}
printf("\n打印成功!!\n");
}
}
int main()
{
SeqQueue* L;
L = CreateQueue();
PrintQueue(L);
EnterQueue(L,5);
PrintQueue(L);
DeleteQueue(L);
PrintQueue(L);
DisposeQueue(L);
return 0;
}