队列简介
什么是队列?
只允许在两端进行插入和删除操作的线性表,在队尾插入,在队头删除 插入的一端,被称为"队尾",删除的一端被称为"队头"
在队列操作过程中,为了提高效率,以调整指针代替队列元素的移动,并将数组作为循环队列的操作空间
结构体
#define N 5
typedef int datatype;
typedef struct
{
datatype data[N];//循环队列的数组
int rear;//存数据端 rear 后面
int front;//取数据端 front 前面
}sequeue_t;
1.创建一个空的队列
sequeue_t *CreateEmptySequeue()
{
sequeue_t *p = (sequeue_t *)malloc(sizeof(sequeue_t));
if(p == NULL)
{
perror("createEmptySequeue err");
return NULL;
}
p->rear = 0;
p->front = 0;
return p;
}
2.入列 data代表入列的数据
int InSequeue(sequeue_t *p,datatype data)
{
//1.容错判断(判满)
if(isFullSequeue(p))
{
perror("isFullSequeue !!");
return -1;
}
//2.从队尾开始入队,队尾rear向后移动
p->data[p->rear]=data;
p->rear=(p->rear+1)%N;
return 0;
}
3.判断队列是否为满
int IsFullSequeue(sequeue_t *p)
{
return (p->rear+1)%N == p->front;
}
4.判断队列是否为空
int IsEmptySequeue(sequeue_t *p)
{
return p->rear == p->front;
}
5.出列
datatype OutSequeue(sequeue_t *p)
{
//1.容错判断(判空)
if(isEmptySequeue(p))
{
perror("isEmptySequeue !!");
return -1;
}
//2.出列数据
//1)暂存数据
datatype temp = p->data[p->front];
//2)移动队头front
p->front = (p->front+1)%N;
return temp;
}
6.求队列的长度
int LengthSequeue(sequeue_t *p)
{
if(p->rear >= p->front)
return p->rear-p->front;
else
return p->rear-p->front + N;
}
7.清空队列函数
void ClearSequeue(sequeue_t *p)
{
p->front = p->rear;
}
总结
循环队列中,假设数组的元素个数为N,那么循环队列中存储最多的数据个数为N-1个
原因:思想上,舍去数组上的一个存储位置,用于判断队列是否为满,先判断rear的下一个位置是否等于front return
(p->rea+1) % N == p->front;
循环队列,如果数组的元素个数为N,那么队列中最多能够存储的数据数的多少? N-1个为什么?
rear后面队尾,在插入的时候,插入之前需要先判断 rear+1,也就是他的下一个位置是否 等于 front 来判断队列是否为满,会造成浪费一个存储位置