循环队列的两种实现方法

循环队列的两种实现方法

顺序存储结构

  示意图参考严蔚敏版《数据结构》。

顺序存储为何宜选循环队列
  队列的顺序表存储中,除了数据域 d a t a data data,还应附设两个坐标 f r o n t front front r e a r rear rear用来记录头结点和尾结点的位置。对于 p o p pop pop操作,依靠 f r o n t + 1 front+1 front+1 这样的上移操作来进行。假设队列中已经有一些元素,经过几次上移后的队列大致如下图所示。

  如图,此时队列已满,画斜线的部分表示被 p o p pop pop 的元素(这些元素虽然被弹出,但由于是顺序表存储,其实际的内存还在)。这时如果想要 p u s h push push新的元素,就应该扩大内存空间——那些被抛弃的元素所占的内存就这样被浪费掉了…这显然不是我们想要的。

是否能循环利用
  当然,之前学习过的循环链表可以作为参考对象。使用顺序存储结构的话,可以利用求余这一重要思想来完成循环(之前做的算法题涉及到循环的操作有好多都是利用求余)。当一个元素被 p o p pop pop后,其所在位置的空间并没有被释放,而是被“假设”不存在了——这只体现在 f r o n t front front标记后移;在空间允许的情况下,新 p u s h push push的元素会覆盖掉之前被 p o p pop pop的元素,一直如是。
  这样的话我们一定要知道一个确定的 M A X _ S I Z E MAX\_SIZE MAX_SIZE
  初始时, f r o n t = r e a r = 0 front=rear=0 front=rear=0,而循环队列下一个则可以用如下公式表示:
( r e a r + 1 ) % M A X _ S I Z E (rear+1)\%MAX\_SIZE (rear+1)%MAX_SIZE
  同样的,在进行 p u s h push push p o p pop pop操作时应该分别进行判满和判空处理。

代码

#include<iostream>
#include<cstdlib>
#define MAX_SIZE 100
#define OK 1
#define ERROR -1
using namespace std;
typedef int ElemType;
typedef int Status;
typedef struct {
	ElemType *data;
	int front, rear;
}SqQueue;
Status QueueInit(SqQueue &sq)
{
	sq.data = (ElemType *)malloc(sizeof(ElemType));
	if (!sq.data)
		return ERROR;
	sq.front = sq.rear = 0;
	return OK;
}
int QueueLength(SqQueue sq)
{
	return (sq.rear - sq.front + MAX_SIZE) % MAX_SIZE;
}
Status Push(SqQueue &sq, ElemType e)
{
	if ((sq.rear + 1) % MAX_SIZE == sq.front) return ERROR;
	sq.data[sq.rear] = e;
	sq.rear = (sq.rear + 1) % MAX_SIZE;
	return OK;
}
Status Pop(SqQueue &sq, ElemType &e)
{
	if (sq.rear == sq.front)
		return ERROR;
	e = sq.data[sq.front];
	sq.front = (sq.front + 1) % MAX_SIZE;
	return OK;
}
int main()
{
	SqQueue sq;
	QueueInit(sq);
	for (int i = 1;i <= 9;i++)
		Push(sq, i);
	for (int i = 1;i <= 4;i++)
	{
		ElemType temp;
		Pop(sq, temp);
		cout << temp << ' ';
	}
	return 0;
}
链式存储结构

代码

#include<iostream>
#include<cstdlib>
#define OK 1
#define ERROR -1
using namespace std;
typedef int ElemType;
typedef int Status;
typedef struct node {
	ElemType data;
	struct node *next;
}Lnode;
Status InitQueue(Lnode *rear)
{
	//rear = (Lnode *)malloc(sizeof(Lnode));
	if (!rear)
		return ERROR;
	rear->next = rear;
	return OK;
}
Status EnQueue(Lnode **rear, ElemType e) 
{
	Lnode *temp = (Lnode *)malloc(sizeof(Lnode));
	if (!temp)
		return ERROR;
	temp->data = e;
	temp->next = (*rear)->next;
	(*rear)->next = temp;
	(*rear) = temp;
	return OK;
}
Status visit(Lnode *rear)
{
	Lnode *temp = rear->next;
	while (temp != rear)  // 存疑2,为何不输出 
	{
		cout << temp->next->data << ' ';
		temp = temp->next;
	}
	return OK;
}
int main()
{
	Lnode *rear;
	rear = (Lnode *)malloc(sizeof(Lnode));
	InitQueue(rear);
	for (int i = 1;i <= 9;i++)
	{
		EnQueue(&rear, i);
		//cout << rear->data << ' ';
	}
	//cout << endl << rear->data;
	visit(rear);
	system("pause");
	return 0;
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值