链式队列
逻辑结构:线性结构
存储结构:链式存储
操作:创建、入列、出列、判空、清空
为了方便我们把头指针与尾指针封装到同一个结构体中,这样我们在传递参数时可以只传递一个linkqueue_t *类型的指针,而不用分别传递头指针和尾指针,可以使代码更简洁。
在创建空队列时(也可以说是创建了一个空的头节点)
p->front = p->rear = (linkqueue_list_t)malloc(sizeof(linkqueue_node_t));
在上面这段代码中,p->front和p->rear同时指向了这个头结点,所以你可以通过修改p->rear->next的值,来改变p->front的值(因为这两个指针指向了同一个地址)。
在整个代码的执行过程中,p->front的指向是不变的,所以只需要改变p->rear的指向。
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data; //数据域
struct node *next; //指针域
} linkqueue_node_t, *linkqueue_list_t;
typedef struct //将队列头指针和尾指针封装到一个结构体里
{
linkqueue_list_t front; //相当于队列的头指针
linkqueue_list_t rear; //相当于队列的尾指针
//有了链表的头指针和尾指针,那么我们就可以操作这个链表
} linkqueue_t;
//1.创建一个空的队列
linkqueue_t *CreateEmptyLinkQueue()
{
linkqueue_t *p = (linkqueue_t *)malloc(sizeof(linkqueue_t));
if (NULL == p)
{
perror("malloc err");
return NULL;
}
p->front = p->rear = (linkqueue_list_t)malloc(sizeof(linkqueue_node_t));
if (NULL == p->rear)
{
perror("p->rear malloc err");
return NULL;
}
p->rear->next = NULL;
p->front->next = NULL;
return p;
}
//4.判断队列是否为空
int IsEmptyLinkQueue(linkqueue_t *p)
{
return p->front->next == NULL;
}
//2.入列 data代表入列的数据
int InLinkQueue(linkqueue_t *p, int data)
{
linkqueue_list_t pnew = (linkqueue_list_t)malloc(sizeof(linkqueue_node_t));
if (NULL == pnew)
{
perror("pnew malloc err");
return -1;
}
pnew->data = data;
pnew->next = NULL;
p->rear->next = pnew;
p->rear = pnew;
}
//3.出列
int OutLinkQueue(linkqueue_t *p)
{
if (IsEmptyLinkQueue(p))
{
perror("list is empty");
return -1;
}
linkqueue_list_t pdel = NULL;
int temp;
if (p->front->next == p->rear)
{
pdel = p->front->next;
temp = pdel->data;
free(pdel);
pdel = NULL;
p->rear = p->front;
p->front->next = NULL;
}
else
{
pdel = p->front->next;
temp = pdel->data;
p->front->next = pdel->next;
free(pdel);
pdel = NULL;
}
return temp;
}
//5.求队列长度的函数
int LengthLinkQueue(linkqueue_t *p)
{
if (IsEmptyLinkQueue(p))
{
perror("list is empty");
return -1;
}
int len = 0;
if (IsEmptyLinkQueue(p))
{
perror("list is empty");
return -1;
}
linkqueue_list_t t = p->front;
while (t->next != NULL)
{
t = t->next;
len++;
}
return len;
}
//6.清空队列
void ClearLinkQueue(linkqueue_t *p)
{
while (!IsEmptyLinkQueue(p))
{
OutLinkQueue(p);
}
}
int main(int argc, char const *argv[])
{
linkqueue_t *p = CreateEmptyLinkQueue();
InLinkQueue(p, 1);
InLinkQueue(p, 2);
InLinkQueue(p, 3);
InLinkQueue(p, 4);
InLinkQueue(p, 5);
for (int i = 0; i < 5; i++)
{
printf("%d ", OutLinkQueue(p));
}
putchar(10);
return 0;
}