链队列是指采用链接存储结构实现的队列。队列中的每个元素单独占有相应大小的存储空间。每个存储单元包括所需要存储的数据,以及下个存储单元的地址指针。可以用下面图一的示意图来表示一个存储单元。
data | next |
图一 存储单元结构示意图
链队列是在对头删除数据元素、队尾插入数据元素的。所以可以分别为队头和队尾设置一个头指针和一个尾指针,头指针和
尾指
向该链队列的队头和队尾。我们可以用结构体来封装。链队列的基本存储单元为一个个节点,用结构体表示链队列的节点:
typedef struct node
{
int data;//用来保存数据
struct node *next;//用来保存下一个节点的地址指针
}Node;
而一个完整的非空链队列就是由这样的一个个节点构成的。看起来比较抽象,下面的示意图可以更为清晰直观地表示一个非空的链队列。
链队列则可以由下面的结构体来表示:
typedef struct
{
Node *front,*rear;//分别表示头指针和尾指针
}LinkQueue;
上图中*Q表示LinkQueue类型的结构体变量,Q->front表示该链队列的头指针,Q->rear表示该链队列的尾指针。
二、链队列的基本算法
(1)当链队列为空时,头指针和尾指针均为空,即中间没有任何的存储节点。那么初始化一个空的队列可以描述为:
LinkQueue* Init(LinkQueue *linkqueue)
{
linkqueue->front=NULL;
linkqueue->rear=NULL;
return linkqueue;
}
(2)链队列插入新节点
队列插入新的节点实在队尾进行的。需要将新的节点插入到队尾后,使原队尾指向新插入节点,同时将队尾指针指向新插入
节点。
void InsertElem2(LinkQueue *linkqueue,int data)
{
Node *newnode;
newnode=new Node;//声明一个新的插入节点
newnode->data=data;//初始化新节点所需存储的数据
newnode->next=NULL;//由于插入位置位于队尾,所以其下个节点的指针为空
if (linkqueue->front==NULL)//当链队列为一个空队列时
{
linkqueue->front=newnode;
linkqueue->rear=newnode;
}
else
{
linkqueue->rear>next=newnode;
linkqueue->rear=newnode;
}
}
(3)删除节点
当队列不为空时,删除节点就是删除队头节点。只需要修改头结点的指针域,队尾指针不变。
LinkQueue* DeleteElem(LinkQueue *linkqueue)
{
if (linkqueue->front==NULL)
{
return linkqueue;
}
else
{
linkqueue->front=linkqueue->front->next;
return linkqueue;
}
}
(4)判断队列是否为空
int Isempty(LinkQueue *linkqueue)//如果链队列为空那么返回1,否则返回0;
{
if (linkqueue->front==NULL)
{
return 1;
}
else
{
return 0;
}
}
(5)打印链队列的所有节点的存储数据
void printElem(LinkQueue *linkqueue)
{
Node *temp=new Node;
temp=linkqueue->front;
if (temp==NULL)
{
cout<<"此链表为空链表!"<<endl;
}
while (temp!=NULL)
{
cout<<temp->data<<endl;
temp=temp->next;
}
}