相关知识
链式队列的定义
队列的存储除了顺序存储之外也可以采用链接存储方式来实现。图 1 描述了队列的一种链接存储实现方案。
该队列存储了 3 个元素 {56,77,15} ,其中 56 为队列头, 15 为队列尾。
这种实现方案中涉及到的两个属性元素如下:
rear: 指向队列尾结点的指针;
next: 指向队列头结点的指针。
当队列是空队列时,rear指向附加头结点,附加头结点的数据项等于 0 ,如图 2 所示。
基于这些属性要素组织成的链表结点的结构定义为:
struct LNode
{
T data;
LNode* next;
};
为了讨论简单,我们假设队列元素的数据类型为整数:
typedef int T; // 队列元素的数据类型
据此,只要给定rear指针,我们就可以对队列进行入队和出队的操作。
在给定图 1 的状态下,进队一个元素 25 以后的状态如图 3 所示:
若出队一个元素是指将当前队列头结点去掉。则在给定图 3 的状态下,进行一次出队后的状态如图 4 所示:
#include <stdio.h>
#include <stdlib.h>
#include "CLnkQueue.h"
LNode* CLQ_Create()
// 创建一个队列
{
LNode* rear=(LNode*)malloc(sizeof(LNode));
rear->data = 0;
rear->next = rear;
return rear;
}
void CLQ_Free(LNode* rear)
// rear指向尾结点
{
CLQ_MakeEmpty(rear);
free(rear);
}
void CLQ_MakeEmpty(LNode* & rear)
// rear指向尾结点
// 将队列变为空队列
{
T item;
while(!CLQ_IsEmpty(rear))
{
CLQ_Out(rear,item);
}
}
bool CLQ_IsEmpty(LNode* rear)
// 判断队列是否为空
{
return rear==rear->next;
}
int CLQ_Length(LNode* rear)
// 返回队列长度,rear指向尾结点
{
return rear->next->data;
}
void CLQ_In(LNode* &rear, T x)
// 入队列, 新结点加入链表尾部。rear指向尾结点
{
LNode* newNode=new LNode;
newNode->data=x;
newNode->next=rear->next;
rear->next=newNode;
rear=newNode;
rear->next->data++;
}
bool CLQ_Out(LNode* & rear, T& item)
// 出队列。空队列时,返回值为false。rear指向尾结点
{
if(CLQ_IsEmpty(rear)) return false;
else if(rear->next->data==1)
{
rear=rear->next;
rear->next=rear;
rear->data--;
}
else
{
LNode* addNode=rear->next;
addNode->next=addNode->next->next;
addNode->data--;
return true;
}
}
bool CLQ_Head(LNode* rear, T& item)
// rear指向尾结点
// 获取队列头。空队列时返回值为false。
{
if (CLQ_IsEmpty(rear))
{
return false;
}
item = rear->next->next->data;
return true;
}
void CLQ_Print(LNode* rear)
// 打印队列
{
if (CLQ_IsEmpty(rear))
{
printf("The queue is: empty. \n");
return;
}
LNode* node=rear->next->next;
do
{
printf("%d ", node->data);
node = node->next;
} while (node != rear->next);
//printf("\n");
}