队列的顺序存储结构(出队元素时不移动元素,只改变队头元素的位置)

// c3-4.h 队列的顺序存储结构(出队元素时不移动元素,只改变队头元素的位置)
#define QUEUE_INIT_SIZE 10 // 队列存储空间的初始分配量
#define QUEUE_INCREMENT 2 // 队列存储空间的分配增量
struct SqQueue2//(见图3.25)
{
	QElemType *base; // 初始化的动态分配存储空间
	int front; // 头指针,若队列不空,指向队列头元素
	int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置
	int queuesize; // 当前分配的存储容量(以sizeof(QElemType)为单位)
};

图326 是根据c3-4.h 定义的有3 个元素的非循环队列。bo3-4.cpp 和bo3-9.cpp 是
这种结构的基本操作。因为后面的程序还要调用bo3-4.cpp,所以将9 个基本操作分别放
在两个文件中。


// bo3-4.cpp 顺序队列(存储结构由c3-4.h定义)的基本操作(5个)
void InitQueue(SqQueue2 &Q)
{ // 构造一个空队列Q(见图3.27)
	if(!(Q.base=(QElemType *)malloc(QUEUE_INIT_SIZE*sizeof(QElemType)))) // 存储分配失败
		exit(ERROR);
	Q.front=Q.rear=0;
	Q.queuesize=QUEUE_INIT_SIZE;
}
void DestroyQueue(SqQueue2 &Q)
{ // 销毁队列Q,Q不再存在(见图3.28)
	if(Q.base)
		free(Q.base);
	Q.base=NULL;
	Q.front=Q.rear=Q.queuesize=0;
}
void ClearQueue(SqQueue2 &Q)
{ // 将Q清为空队列
	Q.front=Q.rear=0;
}
Status QueueEmpty(SqQueue2 Q)
{ // 若队列Q为空队列,则返回TRUE;否则返回FALSE
	if(Q.front==Q.rear) // 队列空的标志
		return TRUE;
	else
		return FALSE;
}
Status GetHead(SqQueue2 Q,QElemType &e)
{ // 若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
	if(Q.front==Q.rear) // 队列空
		return ERROR;
	e=Q.base[Q.front];
	return OK;
}
// bo3-9.cpp 顺序非循环队列(存储结构由c3-4.h定义)的基本操作(4个)
int QueueLength(SqQueue2 Q)
{ // 返回Q的元素个数,即队列的长度
	return(Q.rear-Q.front);
}
void EnQueue(SqQueue2 &Q,QElemType e)
{ // 插入元素e为Q的新的队尾元素(见图3.29)
	if(Q.rear==Q.queuesize)
	{ // 队列满,增加存储单元
		Q.base=(QElemType *)realloc(Q.base,(Q.queuesize+QUEUE_INCREMENT)*sizeof(QElemType));
		if(!Q.base) // 增加单元失败
			exit(ERROR);
	}
	Q.base[Q.rear++]=e;
}
Status DeQueue(SqQueue2 &Q,QElemType &e)
{ // 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR(见图3.30)
	if(Q.front==Q.rear) // 队列空
		return ERROR;
	e=Q.base[Q.front++];
	return OK;
}
void QueueTraverse(SqQueue2 Q,void(*vi)(QElemType))
{ // 从队头到队尾依次对队列Q中每个元素调用函数vi()
	int i=Q.front;
	while(i!=Q.rear)
		vi(Q.base[i++]);
	printf("\n");
}




// main3-4.cpp 顺序队列(非循环),检验bo3-4.cpp和bo3-9.cpp的主程序
#include"c1.h"
typedef int QElemType;
#include"c3-4.h"
#include"bo3-4.cpp" // 基本操作(1)
//#include"bo3-9.cpp" // 基本操作(2)
void print(QElemType i)
{printf("%d ",i);
}
void main()
{
	Status j;
	int i,n=11;
	QElemType d;
	SqQueue2 Q;
	InitQueue(Q);
	printf("初始化队列后,队列空否?%u(1:空0:否)\n",QueueEmpty(Q));
	printf("队列长度为%d\n",QueueLength(Q));
	printf("请输入%d个整型队列元素:\n",n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&d);
		EnQueue(Q,d);
	}
	printf("队列长度为%d\n",QueueLength(Q));
	printf("现在队列空否?%u(1:空0:否)\n",QueueEmpty(Q));
	printf("现在队列中的元素为\n");
	QueueTraverse(Q,print);
	DeQueue(Q,d);
	printf("删除队头元素%d\n",d);
	printf("队列中的元素为\n");
	QueueTraverse(Q,print);
	j=GetHead(Q,d);
	if(j)
		printf("队头元素为%d\n",d);
	else
		printf("无队头元素(空队列)\n");
	ClearQueue(Q);
	printf("清空队列后, 队列空否?%u(1:空0:否)\n",QueueEmpty(Q));
	j=GetHead(Q,d);
	if(j)
		printf("队头元素为%d\n",d);
	else
		printf("无队头元素(空队列)\n");
	DestroyQueue(Q);
}
/*

初始化队列后,队列空否?1(1:空0:否)
队列长度为0
请输入11个整型队列元素:
0 1 2 3 4 5 6 7 8 9 10
队列长度为11
现在队列空否?0(1:空0:否)
现在队列中的元素为
0 1 2 3 4 5 6 7 8 9 10
删除队头元素0
队列中的元素为
1 2 3 4 5 6 7 8 9 10
队头元素为1
清空队列后, 队列空否?1(1:空0:否)
无队头元素(空队列)
*/

c3-4.h 定义的队列顺序存储结构,在出队元素时,只是改变头指针的位置,不移动元
素,可简化操作,节约时间,这从DeQueue()函数和图330 可看出。但这种队列顺序存
储结构也有它的缺点,队列的每个存储空间自始至终只能存一个队列元素。即使这个队列
元素出队后,其它的队列元素也不能占用这个存储空间。尤其在队列长度不长,入队出队
频繁的情况下,存储空间浪费较大。由于没有其它数据覆盖,当队头元素出队后,其值还
保留在队列中。后面的algo3-11.cpp(另一种求迷宫方法)就利用了c3-4.h 的这个特点。

转载于:https://www.cnblogs.com/KongkOngL/p/3945960.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值