顺序队列(循环队列)和链队列的C代码实现

构造队列的初始套路是:定义队列参数结构体,参数赋值成空队列特征

链队列前言:

链队列参数:front,rear 

front指向头节点,rear指向队尾

1,  定义一个队列(参数结构体)

2,  分配头节点,front和rear指向头节点,即空队列

空队列是可描述的:front== rear ==头节点

思考:为什么要引入头节点,而不是front = rear = NULL?

答:如果没有头节点,第一次入队需要修改front,最后一个节点出队,需要修改rear,麻烦!

顺序队列前言:

顺序队列参数:base,front,rear

base 初始队列容量的基址,用于操作各个队列元素

front指向队头(有效元素),rear指向队尾元素的下一个空位

1,  定义一个队列(参数结构体)

2,  分配一定空间的连续存储空间

3,  front = rear = 0;

重要概念:

顺序队列要是循环队列,不然会随着出队入队造成空间的浪费。

如何实现空间的循环利用?

答:N个连续的存储单元,第一个单元编号是0,最后一个单元是N-1;

i代表任意一个单元的编号,++i % N能实现i的值从0走到N-1再自动回到0,依次循环往复。

空队列:front = rear

队满:(rear + 1)% N = front

难点:怎样通过rear和front计算队列元素的个数。

链队列C代码:
typedef struct Node
{
	ElemType data;
	struct Node* next;
}QNode;//结点包括指针域和数据域
typedef struct 
{
	QNode* front;
	Qnode* rear;
}Queue;//队列参数
Status InitQueue(Queue*Q)
{
	(*Q).front = (*Q).rear = (QNode*)malloc(sizeof(QNode));
	if(!(*Q).front)
		exit(-1);
	(*Q).front->next = NULL;
	return ok;
}//初始化,空队列
Status DestoryQueue(Queue*Q)
{
	while((*Q).front)
	{
		(*Q).rear = (*Q).front->next;
		free((*Q).front);
		(*Q).front = (*Q).rear;
	}
	return ok;
}
Status ClearQueue(Queue*Q)
{
	QNode*q,*p;
	(*Q).rear = (*Q).front;//都指向头节点
	p = (*Q).front->next;
	(*Q).front->next = NULL;//头节点指针域为空
	while(p)
	{
		q = (*p).next;
		free(p);
		p = q;
	}
	return ok;
}
Status QueueEmpty(Queue Q)
{
	return ((Q).front==(Q).rear)?true:false;
}
int QueueLength(Queue Q)
{
	int i = 0;//计数器
	while(Q.front!=Q.rear)
	{
		++i;
		Q.front = Q.front->next;
	}
	return i;
}
Status EnQueue(Queue*Q,ElemType e)
{
	QNode* p = (QNode*)malloc(sizeof(QNode));
	if(!p)
		exit(-1);
	(*p).data = e;
	(*p).next = NULL;
	(*Q).rear->next = p;
	(*Q).rear = p;
	return ok;
}
Status DeQueue(Queue*Q,ElemType* e)
{
	QNode* p;
	if(QueueEmpty(*Q))
		return error;//非空队列才能出队列
	p = (*Q).front->next;
	*e = p->data;
	(*Q).front->next = p->next;
	if(p==(*Q).rear)//出队可能改变谁是队尾,要更新参数
		(*Q).rear = (*Q).front;
	free(p);
	p = NULL;
	return ok;
}
void TraverseQueue(Queue Q)
{
   if(QueueEmpty(Q))
      return error;
	QNode* p = Q.front->next;
	while(p!=Q.rear)
	{
		printf("%d  ",p->data);
		p = p->next;
	}
	printf("%d\n",Q.rear->data);
}
/*顺序队列C代码
  顺序队列也叫循环队列,之所以循环,是为了避免由于入队和出队
  过程造成的空间浪费,使空间循环利用*/
typedef struct  
{
	ElemType* base;//操控每个元素
	int front;//队头
	int rear;//队尾
}SqQueue;//顺序队列参数
Status InitSqQue(SqQueue*Q)
{
	(*Q).base = (ElemType*)malloc(sizeof(ElemType)*MAXSIZE);
	if(!(*Q).base)//分配队列容量
		exit(-1);
	(*Q).front = (*Q).rear = 0;//空队列
	return ok;
}
Status ClearSqQue(SqQueue*Q)
{
	(*Q).front = (*Q).rear = 0;
	return ok;//恢复初始化状态即为空队列
}
Status SqQueEmpty(SqQueue Q)
{
	return Q.front==Q.rear?true:false;
}
Status SqQueFull(SqQueue Q)
{
	return (Q.rear+1)%MAXSIZE == Q.front?true:false;
}
int SqQueLength(SqQueue Q)
{
	return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;
}
Status EnSqQue(SqQueue*Q,ElemType e)
{
	if(SqQueFull(*Q))
		return error;//队列不能满才能入队
	(*Q).base[(*Q).rear] = e;
	(*Q).rear = ((*Q).rear+1)%MAXSIZE;
	return ok;
}
Status DeSqQue(SqQueue*Q,ElemType*e)
{
	if(SqQueEmpty(*Q))
		return error;//队列不空才能出队
	*e = (*Q).base[(*Q).front];
	(*Q).front = ((*Q).front+1)%MAXSIZE;
	return ok;
}
Status TraverseSqQue(SqQueue Q)
{
	if(SqQueEmpty(Q))
		return error;
	while(Q.front!=Q.rear)
	{
		printf("%d  ",Q.base[Q.front]);
		Q.front = (Q.front+1)%MAXSIZE;
	}
	printf("\n");
	return ok;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值