#include<stdio.h>
#include<malloc.h>
typedef struct Queue
{
int * pBase; //数组,数组的首地址
int len; //数组长度
int front; //队首
int rear; //队尾
}QUEUE;
void init_queue(QUEUE *); //初始化
bool en_queue(QUEUE *, int val); //入队
void traverse_queue(QUEUE *); //遍历
bool full_queue(QUEUE *); //是否队满
bool out_queue(QUEUE *, int * pVal); //出队
bool empty_queue(QUEUE *); //是否队空
int main(void)
{
Queue Q; //定义后还未赋值
int val; //用来返回出队元素的值
init_queue(&Q); //初始化
en_queue(&Q,1); //入队
en_queue(&Q,2);
en_queue(&Q,3);
en_queue(&Q,4);
en_queue(&Q,5);
en_queue(&Q,6);
en_queue(&Q,7);
traverse_queue(&Q);
if( out_queue(&Q,&val) )
{
printf("出队成功,删除的值为:%d\n",val);
}
else{
printf("出队失败!\n");
}
traverse_queue(&Q);
return 0;
}
void init_queue(QUEUE * pQ) //初始化函数
{
printf("请输入队列的容量:");
scanf("%d",&pQ->len);
//这里本来写的是 scanf("%d",pQ->len);忘了加取址符,导致输入len失败,将数值输入进数值中显然不合适
pQ->pBase = (int *)malloc(sizeof(int) * (pQ->len+1) );
//为数组分配空间,考虑到为了区分队满和队空,我们舍弃了一个元素的空间,在这里先加上
//队首队尾都指向数组下标0
pQ->front = 0;
pQ->rear = 0;
}
bool en_queue(QUEUE * pQ, int val)
{
if( full_queue(pQ) )
{
printf("%d入队失败!\n",val);
return false;
}
else
{
pQ->pBase[pQ->rear] = val;
pQ->rear = (pQ->rear + 1) % (pQ->len+1);
return true;
}
}
bool full_queue(QUEUE * pQ)
{
if( (pQ->rear + 1) % (pQ->len+1) == pQ->front )
/*
判断是否满算法解析
1.为了区分队满和队空(因为他们都可以用队尾等于队首来表示)
我们将牺牲数组中一个元素的空间,当队尾指针指向这个空间时(队尾指针指向最后一个有效位后一位)
这时候就判断循环队列已经满了,这样就可以避免队满和队空判断方式的冲突
2.判断方式: (pQ->rear + 1)%(len + 1) == pQ->front
(pQ->rear + 1)%(len + 1) //队尾加一取余数组长度,这个算法意义在于:
首先如果 pQ->rear + 1没有超过数组范围的话,它必然小于数组长度,经过取余求出的还是它本身
其次如果此时 pQ->rear恰好指向数组的最后一个元素,我们将它加一后就正好等于数组长度
(因为数组下标是从零开始的,最高位下标显然等于数组长度-1),
因此在rear指向数组最后一个元素下标的时候,取余的结果恰好为0,rear从0重新开始
通过这个巧妙的算法判断,使得不管ps->rear下标为多少,我们永远都能算出它的下一位
3.另外要注意的是,因为我们舍弃了数组中的一个元素,
所以实际上的数组长度应该是我们所输入的数组长度+1
*/
{
return true;
}
else
{
return false;
}
}
void traverse_queue(QUEUE * pQ)
{
int i = pQ->front;
printf("循环队列中的元素是:");
while (i != pQ->rear)
{
printf("%d ",pQ->pBase[i]);
i=(i+1) % (pQ->len+1);
}
printf("\n");
return;
}
bool empty_queue(QUEUE * pQ)
{
if( pQ->front == pQ->rear )
return true;
else
return false;
}
bool out_queue(QUEUE * pQ, int * pVal)
{
if( empty_queue(pQ) )
{
return false;
}
else
{
*pVal = pQ->pBase[pQ->front]; //将要删除的值赋给pVal
pQ->front = (pQ->front + 1) % (pQ->len + 1);
return true;
}
}
数据结构自学——(4)队列的代码实现
最新推荐文章于 2023-03-23 21:03:14 发布