目录
1 队列
1.1 队列的概念
像栈一样,队列也是一种线性表。它允许在表的一端插入数据,在另一端删除元素。
插入元素的这一端称之为队尾。删除元素的这一端我们称之为队首。
队列的特性:
- 在队尾插入元素,在队首删除元素。
- 先进先出(排队一样)
1.2 队列的基本操作
InitQueue(&Q):初始化队列,构造一个空队列Q。
DestroyQueue(&Q):销毁队列。销毁并释放队列Q所占用的内存空间。
EnQueue(&Q,x):入队,若队列Q未满,将x加入,使之成为新的队尾。
DeQueue(&Q,&x):出队,若队列Q非空,删除队头元素,并用x返回。
GetHead(Q,&x):读队头元素,若队列Q非空,则将队头元素赋值给x。 其他常用操作:
QueueEmpty(Q):判队列空,若队列Q为空返回true,否则返回false。
2.循环队列
2.1 循环队列概念
设立两个指针:
一个队首指针front ,指向队首元素
一个队尾指针rear ,指向队尾元素的后一个位置(下一个应该插入的位置)·
-
注意事项:
1.入队可能会越界?
如果是在普通的队列中,那么插入元素,直接将tail + 1即可,但是可能会出现“假溢出现象”,即队尾满了,队头有空却无法插入,所以采用循环队列。可是在长度为n的循环队列中,元素插入的位置可能是原来队首的位置,这样如果直接用tail + 1就会造成越界。所以我们计算数组下标的时候要进行取模。使用( tail + 1 ) % n。同理,删除元素也是类似。
2.如何判断队列是否为空,队列是否为满呢?
从上面的图可以看出当tail == head的时候,这个是否队列是即可以为空,又可以为满。那么我们不妨将队列最后一个元素的位置空出来,少用一个存储空间。
这样的话当tail == head的时候,队列为空。当队列的tail + 1 == head,就认为队列已经满了,因为是循环队列,所以计算tail + 1 == head应该算上偏移量即 ( tail + 1 ) % n = head % n。
2.2 循环队列基本操作
-
2.2.1 定义循环队列
#define MaxSize 100 //最大队列长度 typedef int ElemType;//ElemType根据实际情况而定,这里假设为int typedef struct { ElemType *base; //初始化动态分配空间 int front; int rear; } SqQueue;