赞
踩
队列(quque)简称队,只允许在表的一端输入,在表的另一端删除(操作受限制的线性表),
把进行插入的一段叫做队尾(表尾),把进入删除的一端叫做队首或队头(表头)。
队列最主要的特点:先进先出,FIFO(first in first out)
队列有其实有三种:顺序队列、 循环队列、链式队列
下面是采用采用顺序存储结构来实现的顺序队
假设栈的元素个数最大不超过正整数MaxSize,所以元素具有同一数据类型(ElemType),用下来方式来声明顺序队列的类型SqQueue:
- #define MaxSize 128 //队列的最大容量
-
- typedef int ElemType; //队列中元素类型
-
- typedef struct
- {
- ElemType data[MaxSize];
- int front; //存储队头元素前一个单元的下标
- int rear; //队尾指针
- }SqQueue;
对于顺序队来说,有以下四个非常重要的要素:
1.队空条件:SQ->front == SQ->rear == -1
2.队满条件:SQ->rear == MaxSize - 1
3.进队操作:先将rear+1,再将元素e放在rear指向的位置
4.出队操作:先将front+1,再将取出front指向的位置上的元素
1)队列初始化
构造一个空的队列SQ,将front和rear指针都指向-1,代码如下:
- void InitQueue(SqQueue *SQ)
- {
- SQ->front = SQ->rear = -1; //把对头和队尾指针同时置-1
- }
2)判断队列是否为空
顺序队列中,判断队列是否为空,只需要判断SQ->front == SQ->rear的条件成立即可,代码如下:
- //判断队列为空
-
- int IsEmpty(SqQueue* SQ)
- {
- if (SQ->front == SQ->rear)
- {
- return 1;
- }
- return 0;
- }
3)判断队列是否为满
顺序队列中,判断队列是否为满,只需要判断SQ->rear == MaxSize - 1的条件成立即可,代码如下:
- //判断队列是否为满
-
- int IsFull(SqQueue* SQ)
- {
- if (SQ->rear == MaxSize-1)
- {
- return 1;
- }
- return 0;
- }
4)入队
在队列不满条件下先将rear+1,再将元素e放在rear指向的位置,因此该操作需要先判断队列是否已满,避免上溢,这里可以调用IsFull(SqQueue* SQ)来判断,代码如下:
- //入队,先将rear+1,将元素e插入到队列SQ中
-
- void EnterQueue(SqQueue* SQ,ElemType e)
- {
- if (IsFull(SQ))
- {
- printf("队列已满\n");
- return 0;
- }
- SQ->rear = SQ->rear + 1; //队尾指针后移一位
- SQ->data[SQ->rear] = e; //在队尾插入元素e
-
- }
5)出队
在队列不空条件下先将front+1,再将取出front指向的位置上的元素,因此该操作需要先判断队列是否为空,避免下溢,这里可以调用IsEmpty(SqQueue* SQ)来判断,代码如下:
- //出队,先将队头指针front后移一位,取出front指向的元素e出
- int DeleteQueue(SqQueue* SQ,ElemType e)
- {
- if (IsEmpty(SQ))
- {
- printf("队列为空!\n");
- return 0;
- }
- SQ->front = (SQ->front)+1; //队尾指针后移一位
- e = SQ->data[SQ->front]; //出队元素值
-
- return e;
- }
6)打印队列中的元素
从队首到队尾,代码如下:
- //打印队列中的与元素
-
- void PrintQueue(SqQueue* SQ)
- {
- assert(SQ);
- int i = SQ->front;
- while(i<SQ->rear)
- {
- printf("%-3d", SQ->data[i]);
- i++;
- }
- printf("\n");
- }
下面是入队、出栈以及打印出队列元素的操作:
- int main()
- {
- SqQueue SQ;
- ElemType e;
- //初始化队列
- InitQueue(&SQ);
- //入队
- EnterQueue(&SQ, 1);
- EnterQueue(&SQ, 2);
- EnterQueue(&SQ, 3);
- EnterQueue(&SQ, 4);
- EnterQueue(&SQ, 5);
- EnterQueue(&SQ, 6);
- EnterQueue(&SQ, 7);
- EnterQueue(&SQ, 8);
- EnterQueue(&SQ, 10);
- EnterQueue(&SQ, 12);
- EnterQueue(&SQ, 15);
- EnterQueue(&SQ, 16);
-
-
-
- //出队
- printf("出队元素为:%d\n", DeleteQueue(&SQ, e));
- printf("\n");
-
- printf("出队元素为:%d\n", DeleteQueue(&SQ, e));
- printf("\n");
-
- printf("队列中的元素为:");
- PrintQueue(&SQ);
- printf("\n");
-
-
-
- return 0;
- }
测试结构如下:
总结:
实际上,我们非常不建议使用顺序队,因为无论是入队还是出队,它们的指针front,rear都是加1,当队列中有元素出队而SQ->rear == MaxSize时,再进行入队,会显示队满,但其实front的前面还要很多空间,造成空间的浪费,存在假溢现象, 所以一般情况下都采用循环队列的方法来解决。
最后再附上完整代码:
- /*
- 设立一个存储队头元素前一个单元的下标front ,一个队尾指针rear ,分别指向存储队头元素前一个单元的下标和队尾元素。
- 初始化:front=rear=-1。
- 队列为空:front=rear。
- 队满:rear=MaxSize。
- 入队:先将rear加1,再将新元素插入rear所指的位置。
- 出队:先将real加1,再删取出front所指的元素。
-
- */
-
- #include <stdio.h>
- #include <assert.h>
- #include <Windows.h>
-
- #define MaxSize 128 //队列的最大容量
-
- typedef int ElemType; //队列中元素类型
-
- typedef struct
- {
- ElemType data[MaxSize];
- int front; //存储队头元素前一个单元的下标
- int rear; //队尾指针
- }SqQueue;
-
- //队列初始化,将队列初始化为空队列
- void InitQueue(SqQueue *SQ)
- {
- SQ->front = SQ->rear = -1; //把对头和队尾指针同时置-1
- }
-
- //判断队列为空
-
- int IsEmpty(SqQueue* SQ)
- {
- if (SQ->front == SQ->rear)
- {
- return 1;
- }
- return 0;
- }
-
- //判断队列是否为满
-
- int IsFull(SqQueue* SQ)
- {
- if (SQ->rear == MaxSize-1)
- {
- return 1;
- }
- return 0;
- }
-
- //入队,先将rear+1,将元素e插入到队列SQ中
-
- void EnterQueue(SqQueue* SQ,ElemType e)
- {
- if (IsFull(SQ))
- {
- printf("队列已满\n");
- return 0;
- }
- SQ->rear = SQ->rear + 1; //队尾指针后移一位
- SQ->data[SQ->rear] = e; //在队尾插入元素e
-
- }
-
- //出队,先将队头指针front后移一位,取出front指向的元素e出
- int DeleteQueue(SqQueue* SQ,ElemType e)
- {
- if (IsEmpty(SQ))
- {
- printf("队列为空!\n");
- return 0;
- }
- SQ->front = (SQ->front)+1; //队尾指针后移一位
- e = SQ->data[SQ->front]; //出队元素值
-
- return e;
- }
-
-
-
- //打印队列中的与元素
-
- void PrintQueue(SqQueue* SQ)
- {
- assert(SQ);
- int i = SQ->front;
- while(i<SQ->rear)
- {
- printf("%-3d", SQ->data[i]);
- i++;
- }
- printf("\n");
- }
- int main()
- {
- SqQueue SQ;
- ElemType e;
- //初始化队列
- InitQueue(&SQ);
- //入队
- EnterQueue(&SQ, 1);
- EnterQueue(&SQ, 2);
- EnterQueue(&SQ, 3);
- EnterQueue(&SQ, 4);
- EnterQueue(&SQ, 5);
- EnterQueue(&SQ, 6);
- EnterQueue(&SQ, 7);
- EnterQueue(&SQ, 8);
- EnterQueue(&SQ, 10);
- EnterQueue(&SQ, 12);
- EnterQueue(&SQ, 15);
- EnterQueue(&SQ, 16);
-
-
-
- //出队
- printf("出队元素为:%d\n", DeleteQueue(&SQ, e));
- printf("\n");
-
- printf("出队元素为:%d\n", DeleteQueue(&SQ, e));
- printf("\n");
-
- printf("队列中的元素为:");
- PrintQueue(&SQ);
- printf("\n");
-
-
-
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。