#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LinkNode{
ElemType data;
struct LinkNode *next;
}LinkNode;
typedef struct{
LinkNode *front,*rear;
}LinkQueue;
//初始化
void InitQueue(LinkQueue &Q){
Q.front=Q.rear=(LinkNode *)malloc(sizeof(LinkNode));//建立头结点
Q.front->next=NULL;
}
//判断空
bool IsEmpty(LinkQueue Q){
if(Q.front==Q.rear){
return true;
}
else{
return false;
}
}
//入队
void EnQueue(LinkQueue &Q,ElemType e){
LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));
s->data=e;
Q.rear->next=s;
Q.rear=s;
s->next=NULL;
}
//出队
bool DeQueue(LinkQueue &Q,ElemType &e){
if(Q.front==Q.rear){
return false;
}
else{
LinkNode *h=Q.front->next;
e=h->data;
Q.front->next=h->next;
if(Q.rear==h){//原队列只有一个节点
Q.rear=Q.front;
}
free(h);
return true;
}
}
//打印队列
void PrintQueue(LinkQueue Q){
LinkNode *p=Q.front->next;
while(p!=NULL){
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
int main()
{
LinkQueue Q;
int e;
InitQueue(Q);
EnQueue(Q,1);
EnQueue(Q,3);
EnQueue(Q,5);
EnQueue(Q,7);
EnQueue(Q,9);
printf("初始队列为: ");
PrintQueue(Q);
DeQueue(Q,e);
printf("改变后: ");
PrintQueue(Q);
printf("出队元素为: %d",e);
return 0;
}
链式队列的结构定义
链式队列通常由两个指针(或引用)组成:
-
队头指针(front):指向队列的第一个元素(即队首元素)的指针。如果队列为空,则队头指针为空(或指向一个特殊标记的节点,称为哑节点或哨兵节点)。
-
队尾指针(rear):指向队列最后一个元素的后一个位置的指针。这样做的目的是为了简化入队操作,使得入队操作只需要修改队尾指针即可。如果队列为空,则队尾指针和队头指针相同(如果使用了哑节点,则指向哑节点)。
链式队列的节点定义
每个节点通常包含两个部分:
- 数据域(data):存储节点的数据。
- 指针域(next):指向下一个节点的指针。
基本操作
1. 入队(Enqueue)
- 创建一个新节点,将新数据存入新节点的数据域。
- 将新节点的指针域指向队尾指针所指向的位置(即原队列的最后一个元素的下一个位置)。
- 修改队尾指针,使其指向新节点。
2. 出队(Dequeue)
- 检查队列是否为空,如果为空则无法出队。
- 保存队头指针所指向的节点的数据(即队首元素)。
- 修改队头指针,使其指向下一个节点(即原队列的第二个元素)。
- 如果出队后队列为空,则队尾指针也需要更新(如果使用哑节点,则不需要)。
3. 查看队首元素(Front)
- 检查队列是否为空,如果为空则无法查看。
- 返回队头指针所指向的节点的数据。
4. 判断队列是否为空(IsEmpty)
- 根据队头指针和队尾指针的位置关系来判断队列是否为空。如果使用哑节点,则当队头指针和队尾指针都指向哑节点时,队列为空;否则,当队头指针和队尾指针相等时,队列为空。
注意事项
- 在链式队列的实现中,通常会使用哑节点来简化边界条件的处理,但这不是必须的。
- 出队操作后,如果队列为空,需要注意更新队尾指针(如果不使用哑节点)。
- 链式队列的动态特性使得它适合处理数据量变化较大的情况。