数据结构:队列
文章目录
1.队列的相关概念
- 队列(Queue)是仅在表尾进行插入操作,在表头进行删除操作的线性表。
- 表尾即an端,称为队尾;表头即a1端,称为队头。
- 它是一种先进先出(FIFO)的线性表。
插入元素称为入队,删除元素称为出队
队列的存储结构伪链队或颀序队(常用循环顺序队)
序号 | 队列相关概念 | 描述 |
---|---|---|
1 | 定义 | 只能在表的一端进行插入运算,在表的另一端进行删除运算的线性表(头删尾插) |
2 | 逻辑结构 | 与同线性表相同,仍为一对一关系。 |
3 | 存储结构 | 顺序队或链队,以循环顺序队列更常见。 |
4 | 运算规则 | 只能在队首和队尾运算,且访问结点时依照先进先出(FIFO)的原则。关键是掌握入队和出队操作,具体实现依顺序队列或链队列的不同而不同。 |
5 | 实现方式 | 根据顺序队列或链队列的不同而有所差异。 |
2.循环对列
定义:只能在表的一端进行插入运算,在表的另一端进行删除运算的线性表
先进先出(First in Firs out)原则
2.1数据类型定义
//循环队列数据类型定义
#define Max_Size 100
typedef int QElemType;
typedef struct {
QElemType* base; //初始化动态存储空间
int front; //头指针
int rear; //尾指针
}SqQueue;
2.2循环队列初始化
把 front 和 rere 初始化为0
//循环队列初始化
void InitSqQueue(SqQueue* Q) {
Q = (SqQueue*)malloc(sizeof(SqQueue));
Q->rear = Q->front = 0;
}
2.3求循环队列的长度
//求循环队列的长度
int SqQueueLength(SqQueue* Q) {
return ((Q->rear - Q->front + Max_Size) % Max_Size);
}
2.4循环队列入队
//循环队列入队
void EntryQ(SqQueue* Q,QElemType e) {
//判断队列是否满
if((Q->rear + 1) % Max_Size == Q->front) {
return;
}
Q->base[Q->rear] = e;
Q->rear = (Q->rear + 1) % Max_Size;
}
2.5循环队列出队
//循环队列出队
void OutQ(SqQueue* Q,QElemType e) {
//判断是否为空
if(Q->rear == Q->front) {
return;
}
e = Q->base[Q->front]; //记录头指针元素
Q->front = (Q->front + 1) % Max_Size;
}
3.链队
若用户无法估计所用队列的长度,则宜采用链队列
3.1链队的类型定义
typedef struct __QueueNode {
QElemType data;
__QueueNode *next;
} QueueNode;
typedef struct __LinkedQueue {
QueueNode *front;//front相当于链表的头指针
QueueNode *rere;//rere指向整个链表的最后一个节点
} LinkedQueue;
3.2链队初始化
void InitQueue(LinkedQueue *Q) {
// front rere 指向同一节点
if (!(Q->front = Q->rere = (QueueNode *)malloc(sizeof(QueueNode)))){
return;
}
Q->front->next = NULL; //使该节点next域为NULL
return OK;
}
3.3链队入队
void EntryQ(LinkedQueue *Q, QElemType e) {
QueueNode *pnew = (QueueNode *)malloc(sizeof(QueueNode));
if (!pnew)
exit(OVERFLOW);
pnew->data = e;
pnew->next = NULL;
Q->rere->next = pnew;
Q->rere = pnew;
}
3.4链队出队
void OutQ(LinkedQueue *Q, QElemType *e) {
if (Q->front == Q->rere)
return ERROR;
QueueNode *pfree = Q->front->next;
*e = pfree->data;
Q->front->next = pfree->next;
//如果删除的节点为队尾,那么释放pfree之后,rere指向未知存储空间
if (Q->rere == pfree)
Q->rere = Q->front;
free(pfree);
}