队列的链式存储表示,实际上就是一个有头指针和尾指针的单链表。
单链表的表头为队头,单链表的表尾为队尾,由队列的性质,表头只能出队,表尾只能入队。
它的结构体描述如下,分2部分,更容易看出来:
typedef int ElemType;
typedef struct LinkNode{ //结点的结构体
ElemType data;
struct LinkNode *next;
}LinkNode;
typedef struct{ //队列(链表)的结构体
LinkNode *fornt, *rear;
}LinkQueue;
第一个结构体表示一个链队(单链表)结点,包含基本的数据域和指针域;
第二个结构体表示链队的头指针和尾指针;
其实也可以放在一个结构体里面表示,如下:
typedef struct LinkNode{
ElemType data;
struct LinkNode *next;
struct LinkNode *fornt, *rear;
}LinkQueue;
链队的基本操作为:
void InitQueue(LinkQueue &Q);
bool IsEmpty(LinkQueue Q);
void EnQueue(LinkQueue &Q, ElemType e);
bool DeQueue(LinkQueue &Q, ElemType &e);
一个测试主函数如下:
int main()
{
int s;
LinkQueue lQueue;
InitQueue(lQueue);
scanf("%d", &s); //循环入队
while(s != 9999)
{
EnQueue(lQueue, s);
scanf("%d", &s);
}
DeQueue(lQueue, s);
printf("出队后,首结点为:%d", lQueue.fornt->next->data);
return 0;
}
运行结果如下:
完整的源程序如下:
#include "stdio.h"
#include "stdlib.h"
typedef int ElemType;
typedef struct LinkNode{ //结点的结构体
ElemType data;
struct LinkNode *next;
}LinkNode;
typedef struct{ //队列(链表)的结构体
LinkNode *fornt, *rear;
}LinkQueue;
/*
typedef struct LinkNode //第二种结构体定义
{
ElemType data;
struct LinkNode *next;
struct LinkNode *fornt, *rear;
}LinkQueue;
*/
void InitQueue(LinkQueue &Q);
bool IsEmpty(LinkQueue Q);
void EnQueue(LinkQueue &Q, ElemType e);
bool DeQueue(LinkQueue &Q, ElemType &e);
int main()
{
int s;
LinkQueue lQueue;
InitQueue(lQueue);
scanf("%d", &s); //循环入队
while(s != 9999)
{
EnQueue(lQueue, s);
scanf("%d", &s);
}
DeQueue(lQueue, s);
printf("出队后,首结点为:%d", lQueue.fornt->next->data);
return 0;
}
void InitQueue(LinkQueue &Q)
{
Q.fornt = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
Q.fornt->next = NULL;
}
bool IsEmpty(LinkQueue Q)
{
if(Q.rear == Q.fornt)
return true;
else
return false;
}
void EnQueue(LinkQueue &Q, ElemType e)
{
LinkNode *q = (LinkNode*)malloc(sizeof(LinkNode));
q->data = e;
q->next = NULL;
Q.rear->next = q;
Q.rear = q;
}
bool DeQueue(LinkQueue &Q, ElemType &e)
{
if(Q.rear == Q.fornt)
return false;
LinkNode *p = Q.fornt->next; //注意:Q.fornt是头结点,出队出的是首结点,所以是Q.fornt->next
e = p->data;
Q.fornt->next = p->next; //头结点不变,将首结点换成下一个结点
if(Q.rear = p) //出队后,若为空,也要变换尾指针
Q.rear = Q.fornt;
free(p);
return true;
}