队列链表实现
结构声明
图示:链表队列结构模型
对此可做 如下声明
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QuenePtr;
typedef struct
{
QuenePtr front; /* 队头指针 */
QuenePtr rear; /* 队尾指针 */
int len;
}LinkQuene;
插入元素e到队尾
图示:空队列情况以及往空队列插入元素
图示:队列非空时的插入情况
/* 插入元素e到队尾 */
Status EnQueue(LinkQueue *Q, QElemType e)
{
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
if(!p)
return ERROR;
p->data = e;
p->next = Q->rear->next;
Q->rear->next = p; /* 插入到尾部 */
Q->rear = p; /* 插入好后再将尾指针指向p */
Q->len++;
return OK;
}
从队头弹出队列元素
图示:将队列元素从队头弹出
图示:只有一个元素的弹出情况
/* 从队头弹出队列元素 */
Status DeQueue(LinkQueue *Q, QElemType *e)
{
if(Q->front == Q->rear)
return ERROR; /* 队列为空 */
QueuePtr p = Q->front->next; /* 指向第一个结点 */
*e = p->data;
Q->front->next = p->next; /* 头结点的next指针指向第一个结点的下面 */
if(Q->rear == p)
Q->rear = Q->front; /* 如果只包含一个结点,删除后需尾指针指向空,需要从指向头结点 */
free(p);
Q->len--;
return OK;
}
完整示例代码
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int QElemType;
#define STACK_INIT_SIZE 100
#define STACK_INCREMENT 10
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front; /* 队头指针 */
QueuePtr rear; /* 队尾指针 */
int len;
}LinkQueue;
/*构造一个空队列 Q */
Status InitQueue(LinkQueue *Q)
{
Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode)); /* 创建头结点 */
if(!Q->front)
return ERROR;
Q->front->next = NULL; /* 设置头结点指向next指向空 */
Q->len = 0; /* 队列个数清零 */
return OK;
}
/* 插入元素e到队尾 */
Status EnQueue(LinkQueue *Q, QElemType e)
{
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
if(!p)
return ERROR;
p->data = e;
p->next = Q->rear->next;
Q->rear->next = p; /* 插入到尾部 */
Q->rear = p; /* 插入好后再将尾指针指向p */
Q->len++;
return OK;
}
/* 从队头弹出队列元素 */
Status DeQueue(LinkQueue *Q, QElemType *e)
{
if(Q->front == Q->rear)
return ERROR; /* 队列为空 */
QueuePtr p = Q->front->next; /* 指向第一个结点 */
*e = p->data;
Q->front->next = p->next; /* 头结点的next指针指向第一个结点的下面 */
if(Q->rear == p)
Q->rear = Q->front; /* 如果只包含一个结点,删除后需尾指针指向空,需要从指向头结点 */
free(p);
Q->len--;
return OK;
}
/* 销毁队列 */
Status DestroyQueue(LinkQueue *Q)
{
/* 直接从头结点开始 */
while(Q->front) {
Q->rear = Q->front->next; /* 让队尾指针指向第一个结点 */
free(Q->front); /* 释放当前结点 */
Q->front = Q->rear; /* 指向下一个结点 */
}
Q->len = 0;
return OK;
}
/* 检测队列是否为空 */
Status QueueEmpty(LinkQueue *Q)
{
if(Q->front == Q->rear)
return TRUE;
else
return FALSE;
}
/* 获取队头元素 */
Status GetHead(LinkQueue *Q, QElemType *e)
{
if(Q->front == Q->rear)
return ERROR;
*e = Q->front->next->data;
return OK;
}
/* 获取队列长度 */
int QueueLength(LinkQueue *Q)
{
return Q->len;
}
/* 清空队列元素 */
Status ClearQueue(LinkQueue *Q)
{
if(!Q->front)
return ERROR;
QueuePtr p = Q->front->next; /* 指向第一个队列元素 */
while(p) { /* 当前结点非空 */
Q->rear = p->next; /* 保存当前结点的下一个结点地址 */
free(p); /* 释放当前结点 */
p = Q->rear; /* 指向下一个结点 */
}
Q->front->next = NULL; /* 释放完之后要让头结点指针指向空 */
Q->rear = Q->front; /* 尾指针同指向头结点 */
Q->len = 0;
return OK;
}
/* 从队头到队尾打印队列 */
void printQueue(LinkQueue * Q)
{
QueuePtr p = Q->front->next; /* 从第一个结点开始 */
while(p) { /* 当前节点不为空 */
printf("%d ",p->data);
p = p->next;
}
printf("
");
}
int main()
{
LinkQueue Queue;
LinkQueue * Q = &Queue;
QElemType e;
// 插入测试
InitQueue(Q);
EnQueue(Q,1);
EnQueue(Q,2);
EnQueue(Q,3);
EnQueue(Q,4);
printQueue(Q);
// 获取长度测试
printf("len %d
",QueueLength(Q));
// 是否为空测试
printf("empty? %d
",QueueEmpty(Q));
// 获取队头测试
GetHead(Q,&e);
printf("head? %d
",e);
// 出队列测试
DeQueue(Q,&e);
printf("e %d
",e);
printQueue(Q);
// 清空队列测试
ClearQueue(Q);
printQueue(Q);
// 销毁队列测试
DestroyQueue(Q);
return 0;
}