链式队列指的是使用链表来实现的队列,操作比较简单
- 定义一个链式队列以及相关宏定义
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */
typedef int Status;
typedef int QElemType; /* QElemType类型根据实际情况而定,这里假设为int */
typedef struct QNode /* 结点结构 */
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct /* 队列的链表结构 */
{
QueuePtr front,rear; /* 队头、队尾指针 */
}LinkQueue;
- 初始化队列
创建一个头结点并且将将队列的头尾指针指向该结点
Status InitLinkQueue(LinkQueue *Q){
//1. 头/尾指针都指向新生成的结点
Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
//2.判断是否创建新结点成功与否
if (!Q->front) {
return ERROR;
}
//3.头结点的指针域置空
Q->front->next = NULL;
return OK;
}
- 销毁队列:遍历整个队列将遍历的结点free
Status DestoryQueue(LinkQueue *Q){
//遍历整个队列,销毁队列的每个结点
while (Q->front) {
//Q->rear在这个相当于一个临时变量temp
Q->rear = Q->front->next;
free(Q->front);
Q->front = Q->rear;
}
return OK;
}
- 将队列Q置空(清空完成后还能够插入数据)
Status ClearQueue(LinkQueue *Q){
QueuePtr p,q;
Q->rear = Q->front;
p = Q->front->next;
Q->front->next = NULL;
while (p) {
q = p;
p = p->next;
free(q);
}
return OK;
}
- 判断队列是否为空
Status QueueEmpty(LinkQueue Q){
if (Q.front == Q.rear)
return TRUE;
else
return FALSE;
}
- 获取队列长度
int QueueLength(LinkQueue Q){
int i= 0;
QueuePtr p;
p = Q.front;
while (Q.rear != p) {
i++;
p = p->next;
}
return i;
}
-
入队列:插入元素e为队列Q的新元素
- 为入队元素分配结点空间,用指针s指向;
- 将新结点s指定数据域.
- 将新结点插入到队尾
- 修改队尾指针
Status EnQueue(LinkQueue *Q,QElemType e){
//为入队元素分配结点空间,用指针s指向;
QueuePtr s = (QueuePtr)malloc(sizeof(QNode));
//判断是否分配成功
if (!s) {
return ERROR;
}
//将新结点s指定数据域.
s->data = e;
s->next = NULL;
//将新结点插入到队尾
Q->rear->next = s;
//修改队尾指针
Q->rear = s;
return OK;
}
-
出队列
- 第一步:判断队列是否为空;
- 第二步:要删除的队头结点暂时存储在p
- 第三步:要删除的队头结点的值赋值给e
- 第四步:原队列头结点的后继p->next 赋值给头结点后继
- 第五步:若队头就是队尾,则删除后将rear指向头结点
- 第六步:free出队的数据结点
Status DeleteQueue(LinkQueue *Q,QElemType *e){
QueuePtr p;
//判断队列是否为空;
if (Q->front == Q->rear) {
return ERROR;
}
//将要删除的队头结点暂时存储在p
p = Q->front->next;
//将要删除的队头结点的值赋值给e
*e = p->data;
//将原队列头结点的后继p->next 赋值给头结点后继
Q->front->next = p ->next;
//若队头就是队尾,则删除后将rear指向头结点.
if(Q->rear == p) Q->rear = Q->front;
free(p);
return OK;
}
网友评论