前言
队列的链式表示称为链队列,它实际上是一个同时带有队头指针和队尾指针的单链表。 头指针指向队头结点,尾指针指向队尾结点,即单链表的最后一个结点(注意与顺序存储的 不同)。
一、什么是链式队列
链式队列,简称"链队列",即使用链表实现的队列存储结构。
链式队列的实现思想同顺序队列类似,只需创建两个指针(命名为 top 和 rear)分别指向链表中队列的队头元素和队尾元素
在创建链式队列时,强烈建议初学者创建一个带有头节点的链表,这样实现链式队列会更简单。
二、实现
1.创建类型,模版
代码如下(示例):
// create linked list queue template
typedef int MY_DATA;
typedef struct Link{
MY_DATA data;
struct Link *next;
}link,*sgllink;
typedef struct{
sgllink front;
sgllink rear;
}lqueue,*llqueue;
2.功能实现
代码如下(示例):
// @ create linked list queue
llqueue createLqueue(){
llqueue lq;
if((lq = (llqueue)malloc(sizeof(lqueue))) == NULL){
printf("malloc linked queue failed!!\n");
return NULL;
}
lq->front = lq->rear = (sgllink)malloc(sizeof(link));
if(lq->front == NULL){
printf("malloc linked node failed!!!\n");
return NULL;
}
lq->front->data = 0;
lq->front->next = NULL;
return lq;
}
// @ enqueue
int enqueue(llqueue lq, MY_DATA data){
sgllink p;
if(!lq){
printf("your \'lq\' is NULL!\n");
return -1;
}
if((p = (sgllink)malloc(sizeof(link))) == NULL){
printf("mallco new node failed!!\n");
return -1;
}
p->data = data;
p->next =NULL;
lq->rear->next= p;
lq->rear = p;
return 0;
}
// @ dequeue
MY_DATA dequeue(llqueue lq){
sgllink p;
if(!lq){
printf("your \'lq\' is NULL!!");
return -1;
}
p = lq->front;
lq->front = p->next;
free(p);
p = NULL;
return (lq->front->data);
}
// @ is empty
int emptyQueue(llqueue lq){
if(!lq){
printf("your \'lq\' is NULL!!");
return -1;
}
return (lq->front == lq->rear ? 1 : 0);
}
int clearQueue(llqueue lq){
sgllink p;
if(!lq){
printf("your \'lq\' is NULL!!");
return -1;
}
printf("clear free:");
while(lq->front->next){
p = lq->front;
lq->front = p->next;
printf("%d ", p->data);
free(p);
p = NULL;
}
return 0;
}
llqueue freeQueue(llqueue lq){
sgllink p;
if(!lq){
printf("your \'lq\' is NULL!!");
return NULL;
}
printf("free:");
while(lq->front){
p = lq->front;
lq->front = p->next;
printf("%d ", p->data);
free(p);
}
printf("\n");
free(lq);
lq = NULL;
return NULL;
}
总结
链队队列中,当有新的数据元素入队,只需进行以下 3 步操作:
1.将该数据元素用节点包裹,例如新节点名称为 elem;
2.与 rear 指针指向的节点建立逻辑关系,即执行 rear->next=elem;
3.最后移动 rear 指针指向该新节点,即 rear=elem;
由此,新节点就入队成功了。
链式队列中队头元素出队,需要做以下 3 步操作:
1.通过 top 指针直接找到队头节点,创建一个新指针 p 指向此即将出队的节点;
2.将 p 节点(即要出队的队头节点)从链表中摘除;
3.释放节点 p,回收其所占的内存空间;