数据结构——顺序队列

        队列是一种功能受限的线性表,在队列的一端进行入队,另一端出队,可以理解为一端插入数据,一端删除数据。所以队列是先进先出,区别于栈。队列常用的是循环队列,但是在循环队列中,还存在一个问题就是如何判断队满和队空的问题,这里我们分别介绍两种解决此问题的方法。

先给int起别名        #define TYPE int

一、额外多申请一个内存空间

这种方法的代价是浪费一个单位的内存空间,在队空时front==rear,队满时(rear+1)%cap == front

这里先确定队列的结构:连续空间的首地址,队列容量,队头下标,队尾下标

创建

//创建
ArrayQueue *create_queue(int cap)
{
	ArrayQueue *queue=malloc(sizeof(ArrayQueue));
	queue->ptr=malloc(sizeof(TYPE)*(cap+1));
	queue->cap=cap+1;
	queue->front=0;
	queue->rear=0;
	return queue;
}

销毁

//销毁
bool destroy_queue(ArrayQueue *queue)
{
	if(!queue) return false;
	free(queue->ptr);
	queue->ptr=NULL;
	free(queue);
	queue=NULL;
	return true;
}

入队

//入队
bool in_queue(ArrayQueue *queue,TYPE val)
{
	if((queue->rear+1)%queue->cap==queue->front) return false;
	queue->ptr[queue->rear]=val;
	queue->rear=(queue->rear+1)%queue->cap;
	return true;
}

出队

//出队
bool out_queue(ArrayQueue *queue)
{
	if(queue->rear==queue->front) return false;
	queue->front=(queue->front+1)%queue->cap;
	return true;
}

取队头

//取队头
bool head_queue(ArrayQueue *queue,TYPE *val)
{
	if(queue->rear==queue->front) return false;
	*val=queue->ptr[queue->front];
	return true;
}

取队尾

//取队尾
bool tail_queue(ArrayQueue *queue,TYPE *val)
{
	if(queue->rear==queue->front) return false;
	*val=queue->ptr[(queue->rear-1+queue->cap)%queue->cap];
	return true;
}

数量

//数量
int cnt_queue(ArrayQueue *queue)
{
	return (queue->rear-queue->front+queue->cap)%queue->cap;
}

遍历

//遍历
void show_queue(ArrayQueue *queue)
{
	int temp=queue->front;
	for(int i=0;i<cnt_queue(queue);i++)
	{
		printf("%d ",queue->ptr[temp++]);
	}
	printf("\n");
}

二、增加数据项

当我们在设计队列的结构时,可以增加一项用来记录队列中的元素数量,这样一来,当数据项为0时队空,当数据项等于队列容量时队满。

typedef struct ArrayQueue
{
	TYPE *ptr;
	int cap;
	int cnt;
	int front;
	int rear;
}ArrayQueue;

创建

//创建
ArrayQueue *create_queue(int cap)
{
	ArrayQueue *queue=malloc(sizeof(ArrayQueue));
	queue->ptr=malloc(sizeof(TYPE)*cap);
	queue->cnt=0;
	queue->cap=cap;
	queue->front=0;
	queue->rear=-1;
	return queue;
}

销毁

//销毁
bool destroy_queue(ArrayQueue *queue)
{
	if(0==queue->cnt) return false;
	free(queue->ptr);
	queue->ptr=NULL;
	free(queue);
	queue=NULL;
	return true;
}

入队

//入队
bool in_queue(ArrayQueue *queue,TYPE val)
{
	if((queue->cnt==queue->cap)) return false;
	queue->rear=(queue->rear+1)%queue->cap;
	queue->ptr[queue->rear]=val;
	queue->cnt++;
	return true;
}

出队

//出队
bool out_queue(ArrayQueue *queue)
{
	if(0==queue->cnt) return false;
	queue->front=(queue->front+1)%queue->cap;
	queue->cnt--;
	return true;
}

取队头

//取队头
bool head_queue(ArrayQueue *queue,TYPE *val)
{
	if(0==queue->cnt) return false;
	*val=queue->ptr[queue->front];
	return true;
}

取队尾

//取队尾
bool tail_queue(ArrayQueue *queue,TYPE *val)
{
	if(0==queue->cnt) return false;
	*val=queue->ptr[queue->rear];
	return true;
}

遍历

//遍历
void show_queue(ArrayQueue *queue)
{  
    int i = queue->front;  
    for (int j = 0; j < queue->cnt; j++) 
	{  
		printf("%d ", queue->ptr[i]);  
	    i = (i + 1) % queue->cap; 
	}  
	printf("\n");  
}

OK完活,到这里我们通过两种方式解决了队满队空的判断问题,在主函数的测试不再过多赘述。

over

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值