本文涉及完整代码及测试代码均已提交至Gitee,大家可以点击链接参考。
鄙人乃一介初学者,文中及代码中难免出错,恳请同志们雅正!
我们在之前使用顺序结构的存储方式实现了队列,其中因为要解决时间复杂性还使用了循环队列来实现。既然队列是一个线性表,那么使用链式结构同样可以实现队列。接下来我们看看如何实现链式队列。
既然是链表,那么肯定和我们之前使用链表时的定义一样,应该定义一个结构体来表示一个结点,其中含有数据域和指针域。
除了结点模型,在链式队列的实现中我们还要考虑队头指针和队尾指针,在这里我们又定义了一个结构体,这个结构体中的成员变量是两个之前定义的结点的指针,其中一个指向头结点,代表队列头。另一个指向尾结点,代表队列尾。
队列结构定义:
typedef int data_t;
//链表中的结点类型定义
typedef struct Node
{
data_t data;//一个结点的数据域
struct Node* next;//一个结点的指针域
}node, * ptrnode;
//队列的定义,这个结构体中存储了指向队列头和队列尾的结点指针
typedef struct linkqueue
{
ptrnode front;//指向队列头结点的结点指针
ptrnode rear;//指向队列尾结点的结点指针
}linkqueue;
有了队列结构的定义,下面我们来实现以下一些基本的队列操作:
既然我们有两个结构体,其中一个表示结点,另一个表示队列。所以我们需要开辟两次动态内存。第一次为表示队列的结构体开辟一块动态内存,来管理维护队列头和队列尾两个指针。第二次为结点开辟一块空间,来管理维护头结点。
当开辟好后应该对其进行初始化。其中头结点的数据域置0,指针域置空NULL。而队列的队头和队尾,因为此时是个空队列,因此二者应该指向同一个位置,也就是头结点的位置。
下面来看代码:
//1. 创建并初始化队列
/***
**** @return 队列指针
**** @para no
****/
linkqueue* queue_init()
{
//申请内存管理队列结构体:
linkqueue* lq = (linkqueue*)malloc(sizeof(linkqueue));
if (lq == NULL)
{
perror("\nqueue malloc failed");
return NULL;
}
//申请内存来管理结点:
ptrnode p = (ptrnode)malloc(sizeof(node));
if (p == NULL)
{
perror("\