c++数据结构中 顺序队列的队首队尾_C语言:数据结构-队列的顺序存储结构及基本操作...

1.队列的顺序存储结构

(1) 顺序队列

用顺存储结构存储的队列称为顺序队列。

(2) 队列的数组方式存储

用长度为MaxSize的一维数组存储队列元素

整型变量front指示队头元素的位置(队头指针)

整型变量rear指示队尾元素的下一个位置(队尾指针)

(3)顺序队列的结构体类型

struct SeqQueue { /*顺序队列的类型定义*/ElemType data[MaxSize]; /*用一维数组存储队列中的元素*/int front,rear; /*队头、队尾指针*/};

struct SeqQueue *sq; /*sq是指向顺序队列类型的指针变量*/

其中ElemType为队列中元素的数据类型,可根据需要指定其具体的类型,如整型int ,字符型char等。data是一维数组,用于存储队列中所有的数据元素,MaxSize为一维数组的长度,即顺序队列的最大存储容量,*sq是指向顺序队列的指针变量。

2.顺序队列的基本操作

和顺序栈一样,顺序队列也有队空、队满和非空非满这三种状态。由于队头指针和队尾指针所指元素的规定不同,表示方法也不同。因此约定

初始化: 令 rear=front=0;队满:rear==MaxSise为真队空:rear==front 为真

假设队列的最大存储空间MaxSize=5,则顺序队列出队和入队时,队头和队尾指针的变化情况如图3-6所示。

08fd65f7f67d6c09a395dd98c284e136.png

顺序队列操作示意图

(1)入队操作

入队是将新元素插入到rear所指的位置,然后再将rear的值加1。

算法要点:

① 检查队列是否已满,若队满,则进行“溢出”错误处理;

② 否则,将元素值x赋给队尾指针所指向的数据单元;

③ 将队尾指针加1。

顺序队列入队算法

void InQueue(struct SeqQueue * sq, int x){if(sq->rear==MaxSize) { /*判队列是否已满*/printf("队列已满");exit(1); /*入队失败,退出函数运行*/ }sq->data[sq->rear]=x; /*数据送给队尾指针所指单元*/ sq->rear++; /*将队尾指针加1*/ }

图3-6(b)是插入两个元素的队列状况。图3-6(c)队列已满,此时尾指针已超越存储空间的上界,如果再进行入队操作,就会产生“上溢”错误。

(2)出队操作

出队是删除front所指位置的元素后,再将front的值加1并返回被删元素。

算法要点:

① 检查队列是否为空队列,若队空,则进行“下溢”错误处理;

② 将队头指针加1;

③ 返回front所指位置的元素。

顺序队列出队算法

ElemType OutQueue(struct SeqQueue *sq){if (sq->rear==sq->front) { /*判断队是否为空*/printf("队列已空,不能进行出队操作");exit(1); /*出队失败,退出函数运行*/}sq->front++;return sq->data[sq->front-1]; /*返回front所指位置的元素*/}

图3-6(d)是删除A元素的队列状况,(e)是继续删除B元素的队列状况。每删除一个元素,front指针加1(后移),以保证front始终指向新的队头元素。在图3-6(d)、(e)状态下,如果有新元素请求入队,此时队列的实际可用空间虽然没有占满,但尾指针已超越存储空间的上界,因此不能进行入队操作。但事实上队列中还有空位置,也就是说,队列的存储空间并没有满,但队列却发生了“上溢”错误,称这种现象为“假上溢”。

在图3-6(f)所示状态下,队列已空,队列的头指针和尾指针均已超越存储空间的上界,此时如果仍要进行出队操作,就会产生“下溢”错误。

从图3-6可以看出,在非空队列里,front指针始终指向队头元素,而rear指针始终指向队尾元素的下一位置。当front指针和rear指针值相等时,队列为空。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
循环顺序队列是一种特殊的队列,它在数组的基础上实现了队列的功能。以下是使用C语言完成该数据结构的代码。 首先,我们需要定义循环顺序队列的结构体: ```c #define MAXSIZE 100 // 循环顺序队列的最大容量 typedef struct { int data[MAXSIZE]; // 存放队列元素的数组 int front; // 头指针 int rear; // 指针 } SqQueue; ``` 其,`front`指向头元素的前一个位置,`rear`指向元素的位置。 接下来,我们需要实现循环顺序队列的入操作: ```c bool EnQueue(SqQueue *Q, int x) { if ((Q->rear + 1) % MAXSIZE == Q->front) { // 队列已满 return false; } Q->rear = (Q->rear + 1) % MAXSIZE; Q->data[Q->rear] = x; return true; } ``` 如果队列已满,即`(rear+1)%MAXSIZE == front`,则返回false;否则,将`x`插入,并更新`rear`指针。 接着,我们需要实现循环顺序队列的出操作: ```c bool DeQueue(SqQueue *Q, int *x) { if (Q->front == Q->rear) { // 队列为空 return false; } Q->front = (Q->front + 1) % MAXSIZE; *x = Q->data[Q->front]; return true; } ``` 如果队列为空,即`front == rear`,则返回false;否则,将头元素出,并更新`front`指针。 最后,我们需要实现循环顺序队列的获取队列长度操作: ```c int QueueLength(SqQueue Q) { return (Q.rear - Q.front + MAXSIZE) % MAXSIZE; } ``` 由于`rear`指向元素,`front`指向头元素的前一个位置,因此队列长度为`(rear-front+MAXSIZE)%MAXSIZE`。 完整代码如下: ```c #include <stdio.h> #include <stdbool.h> #define MAXSIZE 100 typedef struct { int data[MAXSIZE]; int front; // 头指针 int rear; // 指针 } SqQueue; bool EnQueue(SqQueue *Q, int x) { if ((Q->rear + 1) % MAXSIZE == Q->front) { return false; } Q->rear = (Q->rear + 1) % MAXSIZE; Q->data[Q->rear] = x; return true; } bool DeQueue(SqQueue *Q, int *x) { if (Q->front == Q->rear) { return false; } Q->front = (Q->front + 1) % MAXSIZE; *x = Q->data[Q->front]; return true; } int QueueLength(SqQueue Q) { return (Q.rear - Q.front + MAXSIZE) % MAXSIZE; } int main() { SqQueue Q; Q.front = Q.rear = 0; int length, x; // 测试入 EnQueue(&Q, 1); EnQueue(&Q, 2); EnQueue(&Q, 3); EnQueue(&Q, 4); EnQueue(&Q, 5); // 测试获取队列长度 length = QueueLength(Q); printf("队列长度为:%d\n", length); // 测试出 while (DeQueue(&Q, &x)) { printf("%d ", x); } return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值