(浙大MOCC学习笔记)队列的顺序存储实现

“队列”类似于堆栈,也是一个有序的线性表。不同于堆栈的插入和删除操作只在一端操作的方式,队列的插入和删除分别在线性表的不同端点进行。

队列的顺序存储结构的可以定义为:

typedef int ElementType;
typedef	int Position;
typedef struct QNode* PtrToQNode;
struct QNode
{
	ElementType* Data;
	Position Front, Rear;
	int MaxSize;
};
typedef PtrToQNode Queue;

其中,在写代码时留意到的几个关键点:

1)注意,定义中,队头Front实际指向的是队列第一个元素前边的那个那块区域,而队尾Rear指向的是队列的最后一个元素。

2)为了避免假溢出,使用了循环队列的方式。队列的最大容量MaxSize并不是队列中实际能存放元素的最大数量!因为如果满队列的状态如下图C所示,其能存放元素的最大数量应该为MaxSize-1

3)由循环列表的特殊性决定了以下两个操作:

       入队→Q->Rear = (Q->Rear+1)%Q->MaxSize;

      出队→Q->Front = (Q->Front+1)%Q->MaxSize

 

完整操作代码如下:

/*队列的ADT:
  1、类型名:队列(Queue)
  2、数据对象及:一个有0个或多个元素的有穷线性表
  3、操作集:
     对于一个长度为正整数MaxSize的队列Q∈Queue,记队列中的任一元素X∈ElementType,队列的基本操作有
	 (1)Queue CreateQueue(int MaxSize):生成空队列,其最大长度为MaxSize
	  (2) bool IsFull(Queue Q):判断队列Q是否已满
	 (3)bool IsEmpty(Queue Q):判断队列Q是否是空的
	 (4)bool AddQ(Queue Q,ElementType X):将元素X压入队尾。若队列已满,返回false
	 (5)ElementType DeleteQ(Queue Q):从队列Q的队头弹出元素。若队列为空,返回错误信息
	 (6)void QueueRead():将一些元素入队,若入队的元素的个数大于队列的最大容量,只入队满队列
	  (7) int QueueLength(Queue Q):输出队列中元素的个数
	 (8)void QueuePrint(Queue Q):将队列中的元素从队头到队尾依次输出 */
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

#define Error -1
typedef int ElementType;
typedef	int Position;
typedef struct QNode* PtrToQNode;
struct QNode
{
	ElementType* Data;
	Position Front, Rear;
	int MaxSize;
};
typedef PtrToQNode Queue;

Queue CreateQueue(int MaxSize)
{
	Queue Q = (Queue)malloc(sizeof(struct QNode));
	Q->Data = (ElementType*)malloc(MaxSize*sizeof(ElementType));
	Q->Front = Q->Rear = 0;
	Q->MaxSize = MaxSize;
	return Q;
}

bool IsFull(Queue Q)
{
	return ((Q->Rear + 1) % Q->MaxSize == Q->Front);
}

bool AddQ(Queue Q, ElementType X)
{
	if (IsFull(Q))
	{
		printf("队列已满\n");
		return false;
	}
	else
	{
		Q->Rear = (Q->Rear + 1) % Q->MaxSize;
		Q->Data[Q->Rear] = X;
		return true;
	}
}

void QueueRead(Queue Q)
{
	if (IsFull(Q))
	{
		printf("队列已满\n");
		return;
	}
	int num, elem;
	int sig;
	printf("请输入要入队的元素的个数:\n");
	scanf("%d", &num);
	printf("请输入要入队的各个元素:\n");
	while (num--)
	{
		scanf("%d", &elem);
		sig = AddQ(Q, elem);
		if (!sig)
			break;
	}
}

bool IsEmpty(Queue Q)
{
	return (Q->Front == Q->Rear);
}

ElementType DeleteQ(Queue Q)
{
	if (IsEmpty(Q))
	{
		printf("队列是空的,无元素\n");
		return Error;
	}
	else
	{
		Q->Front = (Q->Front + 1) % Q->MaxSize;
		return Q->Data[Q->Front];
	}
}

int QueueLength(Queue Q)
{
	if (Q->Rear < Q->Front)
		return (Q->Rear + Q->MaxSize - Q->Front);
	else
		return(Q->Rear - Q->Front);
}

void QueuePrint(Queue Q)
{
	if (IsEmpty(Q))
	{
		printf("队列是空的");
		return;
	}
	int i = Q->Front;
	int j = Q->Rear;
	while (i != j)
	{
		i = (i + 1) % (Q->MaxSize);
		printf("%d ", Q->Data[i]);
	}
}

int main()
{
	//设定队列的最大容量 
	int maxsize;
	printf("请输入队列数组的最大容量:");
	scanf("%d", &maxsize);
	printf("该队列最多入队%d个元素\n", maxsize - 1);
	//创建一个顺序存储的队列 
	Queue Q = CreateQueue(maxsize);
	printf("此时队列中元素的个数为:%d\n", QueueLength(Q));
	//选择将元素入队 
	QueueRead(Q);
	printf("队列中元素的个数为:%d\n", QueueLength(Q));
	//输出队列中的各个元素(从队头到对位) 
	QueuePrint(Q);

	printf("\n\n");

	printf("请您选择出队元素的个数:\n");
	int length;
	scanf("%d", &length);
	if (length>QueueLength(Q))
	{
		printf("您选择数超过了队列元素个数,错误!!!\n");
		return 0;
	}
	if (length == 0)
	{
		printf("没有任何元素需要出队\n");
	}
	else
	{
		int elem;
		printf("从队头到队尾,出列的元素分别为:\n");
		while (length--)
		{
			elem = DeleteQ(Q);
			printf("%d ", elem);
		}
		printf("\n");
	}
	printf("出队后,队列的长度为:%d\n", QueueLength(Q));
	printf("出队后,队列中的元素为:");
	QueuePrint(Q);
	printf("\n");
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值