C语言实现顺序队列

有关C语言实现队列

1.队列也是一种运算受限制的线性表,它只允许在表的一段(front)进行插入,在另一端(rear)进行删除。
2.队列亦称作先进先出的线性表,注意不能称为后进后出。
在这里插入图片描述
#define MAX 5

//顺序队列结构描述
struct Sq_Queue
{
Elemtype data[MAX];
Elemtype front;//对头指针
Elemtype rear;//对尾指针
};
typedef struct Sq_Queue SqQueue;

SqQueue Q;

为方便起见,规定front指向当前对头元素,rear指向当前队尾所在位置的下一个位置,所以队列总会有一个位置不放数据元素。

于是,一开始初始化都让front,rear为0,若不考虑溢出,入队的操作为
Q.data[Q.rear]=data;
Q.rear++;//尾指针加1

若不考虑队空,出队的操作为,其中temp为第三者,用来当函数的返回值
temp=Q.data[Q.front];
Q.front++;//头指针加1

显然此时,判断队满的条件为
(Q.rear)-(Q.front)=MAX-1,此时再做入队操作则会上溢,此情况称为真溢出,假溢出的情况后面解决。

判断队空的条件为
Q.front==Q.rear

假溢出的原因是:如果当前尾指针等于向量的上界(即Q.rear==MAX-1),即使队列不满(即当前队列长度小于MAX-1),再入队操作也会引发溢出。
在这里插入图片描述
如此时队列还有两个空位,但是再入队(即Q.rear++大于MAX-1)就会溢出,
产生该现象的原因是:被删元素的空间在该元素删除以后就永远是用不到。
为客服这个问题,下面介绍一种方法。

即设想(注意是设想!!)向量Q.data[MAX]是一个首尾相接的圆环,即Q.data[0]接在Q.data[MAX-1]后面,我们称这种意义下的向量称为循环向量,并将循环向量中的队列称为循环队列。再回到上面假溢出的情况,此时再做入队操作时,令尾指针等于向量的下界,这样就能利用已被删除的元素空间,克服假上溢现象。
此时,入队操作为(判断队满情况下面介绍)
Q.data[Q.rear]=data;
Q.rear=(Q.rear+1)%MAX;
出队操作为
temp=Q.data[Q.front];
Q.front=(Q.front+1)%MAX;
为什么要用%即模运算,看回上图,若此时再入队,那么Q.rear=(4+1)%5=0,就入队成功了。
判断队满的条件为:(Q.rear+1)%MAX=Q.front
判断队空的条件为:Q.front=Q.rear

下面贴上代码

#include <stdio.h>
#include <stdlib.h>


#define MAX 5
#define OK 1
#define ERROR -1
#define QUEUE_SIZE 100 

typedef int Elemtype;


//顺序队列结构描述 
struct Sq_Queue
{
	Elemtype data[MAX];
	Elemtype front;//队头指针 
	Elemtype rear;//队尾指针 
};
typedef struct Sq_Queue SqQueue;


//初始化队列 
void InitSqQueue(SqQueue &Q)
{
	Q.front=0;
	Q.rear=0;
	
	printf("\n---success---\n");
}



//入队函数 
void AddQueue(SqQueue &Q,Elemtype data)
{
	if((Q.rear+1)%MAX==Q.front)
	   printf("\n***Full***\n");
	   
    else
    {
	    Q.data[Q.rear]=data;
    	Q.rear=(Q.rear+1)%MAX;
    	
    }
}


//出队函数
Elemtype DelQueue(SqQueue &Q)
{
	Elemtype temp;
	
	if(Q.front==Q.rear)
	  printf("\n***Empty***\n");
	else
	{
		temp=Q.data[Q.front];
		Q.front=(Q.front+1)%MAX;
	}  
	
	return temp;
} 


//打印队列函数
void printf_SqQueue(SqQueue &Q)
{
	Elemtype temp;
	
	temp=Q.front;
	
	if(Q.front==Q.rear)
	   printf("***Empty***\n");
	else
	{
		printf("输出该队列:");
		while(Q.front!=Q.rear)
		{
			printf(" [%d] ",Q.data[Q.front]);
			Q.front=(Q.front+1)%MAX;
		}
	}
	
	printf("\n");
	Q.front=temp;   
} 



int main(int argc, char *argv[])
{
	Elemtype temp,temp1,temp2;
	
	SqQueue Q;
	
	InitSqQueue(Q);
	
	do
	{
		printf("\n***请输入你想执行的功能***\n");
		printf("(1)入队  (2)出队   (3)EXIT\n");
		scanf("%d",&temp);
		
		switch(temp)
		{
			
			case 1:
			{
				printf("请输入你想入队的数据:");
				scanf("%d",&temp1);
				
				AddQueue(Q,temp1);
				printf_SqQueue(Q);
			}break;
			
			case 2:
			{
				temp2=DelQueue(Q);
				printf("出队的数据为:(%d)\n",temp2);
				
				printf_SqQueue(Q);
			}break;
			
		} 
		
	}
	while(temp!=3);
	
	
	printf("\n****感谢您的使用****\n"); 
	printf("\n");
	
	
	return 0;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值