隊列的鏈式存儲表示,實際上就是一個有頭指針和尾指針的單鏈表。
單鏈表的表頭爲隊頭,單鏈表的表尾爲隊尾,由隊列的性質,表頭只能出隊,表尾只能入隊。
它的結構體描述如下,分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;
}