1.队列特点(FIFO)
数据满足“先进先出,后进后出”存取特点的数据结构
(1)逻辑结构:线性
(2)存储结构:顺序,链式
(3)运算:初始化,入队,出队,对空,队满判断(顺序队列)
2.顺序队列
队列管理结构体
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int DataType;
//队列管理结构
typedef struct node
{
DataType *queue; //队列指针
int size; //队列空间大小
int front; //队头元素偏移两
int rear; //队尾元素偏移量
}SequentQueue;
//初始化、队满、对空、出队、入队、遍历
//初始化
SequentQueue *InitQueue(int size)
{
SequentQueue * q = malloc(sizeof(SequentQueue));
if(q!=NULL)
{
q->queue = calloc(size,sizeof(DataType));
q->size=size;
q->front=0;
q->rear=0;
return q;
}
}
//队空判断
bool IsQueueEmpty(SequentQueue *q)
{
return (q->rear == q->front);
}
//队满判断
bool IsQueueFull(SequentQueue *q)
{
return ((q->rear+1) % q->size == (q->front));
}
//入队操作
bool EnQueue(SequentQueue *q,DataType data)
{
if(IsQueueFull(q)||q==NULL)
return false;
// 将rear往后偏移
//*(q->queue + q->rear) = data;
q->rear = (q->rear+1) % q->size;
//填数据
q->queue[q->rear]=data;
return true;
}
//出队操作
bool DeQueue(SequentQueue *q,DataType *data)
{
if(IsQueueEmpty(q)||q==NULL)
return false;
//将front往后移动
//*data = *(q->queue + q->front);
q->front = (q->front+1) % q->size;
//拿数据
*data = q->queue[q->front];
return true;
}
void Display(SequentQueue *q)
{
int front,rear,data;
if(IsQueueEmpty(q)||q==NULL)
return;
front = q->front;
rear = q->rear;
while(front != rear)
{
front=(front+1)%q->size;
data = q->queue[front];
printf("%d ",data);
}
}
3.链式队列
节点结构体,管理结构体
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int DataType;
//队列节点
typedef struct node
{
DataType data;
struct node *next;
}LinkNode;
//管理结构体
typedef struct
{
struct node *front; //队头指针
struct node *rear; //队尾指针
unsigned int size; //当前元素个数
}LinkQueue;
初始化、队空判断,入队,出队,遍历
//初始化
LinkQueue *InitLinkQueue(void)
{
LinkQueue *q=(LinkQueue *)malloc(sizeof(LinkQueue));
if(q!=NULL)
{
q->front=NULL;
q->rear=NULL;
q->size=0;
return q;
}
return q;
}
//判断队空
bool IsQueueEmpty(LinkQueue *q)
{
return (q->size == 0);
}
LinkNode *CreatNode(DataType data)
{
LinkNode * newNode = (LinkNode *)malloc(sizeof(LinkNode));
if(newNode!=NULL)
{
newNode->data=data;
newNode->next=NULL;
return newNode;
}
}
//入队
bool EnQueue(LinkQueue *q,LinkNode *newNode)
{
if(newNode == NULL)
return false;
if(IsQueueEmpty(q))
{
//第一个数据进来,那么队头和队尾都指向这个节点
q->front=newNode;
q->rear=newNode;
}
else
{
//将新节点按照链表尾插的方式加入链表
q->rear->next = newNode;
//new就要作为队的新队尾节点
q->rear = newNode;
}
q->size++;
return true;
}
//出队
bool DeQueue(LinkQueue *q,LinkNode **nodeData)
{
if(IsQueueEmpty(q))
return false;
//将队头的数据拿到
*nodeData = q->front;
//队头要重新变到下一个节点
q->front=q->front->next;
q->size--;
return true;
}
bool DeQueue1(LinkQueue* q, DataType *data)
{
//队列为空
if (IsQueueEmpty(q))
{
return false;
}
if (q->size == 1)
{
q->rear = NULL;
}
//将队头的数据拿到
*data = q->front->data;
//队头要重新变到下一个节点
q->front = q->front->next;
q->size--;
return true;
}
//遍历链表
void Display(LinkQueue *q)
{
LinkNode *tmp=q->front;
while(tmp != NULL)
{
printf("%d ",tmp->data);
tmp=tmp->next;
}
printf("\n");
}