队列的链式存储结构相对顺序存储结构而言,数据元素的个数可以不受限制,更为灵活。在不知道存取数据最大个数的情况下优先采取链式存储结构。
但是,链式队列在插入和删除的时候涉及到存储空间的分配和释放,这无疑增加了时间开销。因此,到底只用哪一种结构,要综合考虑。
以下,给出C语言版的链式存储结构。
/*******************************************************************/
//描述:队列的顺序存储结构,该队列为循环队列,队列的创建,插入,删除等基本操作的函数,以及对这些操作进行验证
//时间:2018.1.3 21:50
//作者:Liu ZhenHua
//*****************************************************************/
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 5
#define OVERFLOW 1
typedef int QElemType;
typedef int Status;
typedef struct QueueNode{ //结点结构
QElemType data;
struct QueueNode *next;
}QueueNode,*QueueNodePtr;
typedef struct{
QueueNodePtr front,rear;
}LinkQueue;
void InitLinkQueue(LinkQueue *Q); //初始化队列指针
Status EnQueue(LinkQueue *Q,QElemType e); //插入新元素
Status DEQueue(LinkQueue *Q,QElemType *e); //删除头元素
int QueueLength(LinkQueue *Q); //获取队列元素数目
void printSL(void); //打印一行分割线
void PrintLinkQueue(LinkQueue *Q); //打印队列元素
int main()
{
LinkQueue *LQ;
QElemType val;QElemType *pval = (QElemType*)malloc(sizeof(QElemType));
LQ = (LinkQueue*)malloc(sizeof(LinkQueue));
printf("新建一个队列。\n");
printSL();
InitLinkQueue(LQ); //初始化队列指针
printf("初始化队列!\n");
printSL();
val = 6;
if(EnQueue(LQ,val))printf("插入元素: %d ,插入成功!\n",val); //插入元素
val = 8;
if(EnQueue(LQ,val))printf("插入元素: %d ,插入成功!\n",val);
val = 10;
if(EnQueue(LQ,val))printf("插入元素: %d ,插入成功!\n",val);
printSL();
printf("队列中元素个数为:%d \n",QueueLength(LQ)); //获取队列长度
printf("打印输出队列中的元素:\n");PrintLinkQueue(LQ);
printSL();
if(DEQueue(LQ,pval))printf("删除队列头元素:%d ;删除成功!\n",*pval); //删除队列中的头元素
printSL();
printf("队列中元素个数为:%d \n",QueueLength(LQ));
printf("打印输出队列中的元素:\n");PrintLinkQueue(LQ);
printf("结束\n");
return 0;
}
/**********************************************/
//函数名: printSL
//描述 : 打印一行分割线Print Split Line
//参数 :结无
//返回值:无
//作者 :LiuZhenHua
/**********************************************/
void printSL(void){
int i;
for(i = 0; i < 20; i++){
printf("-");
}
printf("\n");
}
/**********************************************/
//函数名: EnQueue
//描述 : 插入元素e为新的队尾元素
//参数 :队列结构体指针,元素e
//返回值:状态值
//作者 :LiuZhenHua
/**********************************************/
Status EnQueue(LinkQueue *Q,QElemType e){
QueueNodePtr node;
node = (QueueNodePtr)malloc(sizeof(QueueNode));
if(!node){
exit(OVERFLOW); //存储分配失败,直接退出整个程序
}
node->data = e;
node->next = NULL;
Q->rear->next = node;
Q->rear = node;
return OK;
}
/**********************************************/
//函数名: DEQueue
//描述 : 删除头元素
//参数 :队列结构体指针,元素指针e
//返回值:状态值
//作者 :LiuZhenHua
/**********************************************/
Status DEQueue(LinkQueue *Q,QElemType *e){
QueueNodePtr p;
if(Q->front == Q->rear){
return ERROR;
}
p = Q->front->next;
*e = p->data;
Q->front->next = p->next;
if(Q->rear == p){ //如果整个队列值由一个元素,那么删除掉一个个元素后,就是空表,则
//尾指针同样需要修改
Q->rear = Q->front;
}
free(p);
return OK;
}
/**********************************************/
//函数名: InitLinkQueue
//描述 : 初始化队列指针
//参数 :队列结构体指针,元素指针e
//返回值:状态值
//作者 : LiuZhenHua
/**********************************************/
void InitLinkQueue(LinkQueue *Q){
QueueNodePtr p;
p = (QueueNodePtr)malloc(sizeof(QueueNode));
p->next = NULL;
Q->front = p;
Q->rear = p;
}
/**********************************************/
//函数名: PrintLinkQueue
//描述 : 打印队列元素
//参数 :队列结构体指针,元素指针e
//返回值:状态值
//作者 : LiuZhenHua
/**********************************************/
void PrintLinkQueue(LinkQueue *Q){
int i=1;
QueueNodePtr p;
p = Q->front;
while(p!=Q->rear){ //只到指向尾指针
p = p->next;
printf("The element %d : %d\n",i++,p->data);
}
}
/**********************************************/
//函数名: PrintLinkQueue
//描述 : 打印队列元素
//参数 :队列结构体指针,元素指针e
//返回值:状态值
//作者 : LiuZhenHua
/**********************************************/
int QueueLength(LinkQueue *Q){ //获取队列元素数目
int i=0;
QueueNodePtr p;
p = Q->front;
while(p!=Q->rear){ //只到指向尾指针
p = p->next;
i++;
}
return i;
}