链式队列
队列的链式存储结构,其实就是线性表的单链表,只不过它只能是尾进头出而已,将其简称为链队列。为了操作上的方便,我们将队头指针指向链队列的头结点,而队尾指针指向终端结点。如下图所示
空队列时,front 和 rear 都指向终端结点,如下图
结构体定义:
typedef struct Node // 结点结构
{
int data; // 定义数据域
struct Node *next; // 定义 next 指针域
}Node;
typedef struct HNode // 队列的链表结构
{
struct Node *front, *rear; // 定义头尾指针
}HNode, *QueueList;
基本操作
void InitQueueL(QueueList queue); // 初始化链式队列
bool Push(QueueList queue, int val); // 入队
bool Pop(QueueList queue, int *rtv); // 出队
void Show(QueueList queue); // 打印队列元素
int GetLength(QueueList queue); // 获取队列长度
bool IsEmpty(QueueList queue); // 判空
void Clear(QueueList queue); // 清空队列
void Destroy(QueueList queue); // 销毁队列
入队操作
链式队列的入队操作其实就是在链表尾部插入结点
出队操作
出队操作时,就是头结点的后继结点出队,若链表除头结点外只剩一个元素时,则需将rear指向头结点,如下图所示。
代码 :
void InitQueueL(QueueList queue)
{
assert(queue != NULL);
queue->last = NULL;
queue->front = NULL;
}
static Node *GetNode(int val)
{
Node *pGet = (Node *)malloc(sizeof(Node));
assert(pGet != NULL);
pGet->data = val;
pGet->next = NULL;
return pGet;
}
bool Push(QueueList queue, int val)
{
Node *pGet = GetNode(val);
if (queue->last == NULL)//第一次插入
{
queue->front = pGet;
}
else
{
queue->last->next = pGet;
}
queue->last = pGet;
return true;
}
bool Pop(QueueList queue, int *rtv)
{
if (IsEmpty(queue))
{
return false;
}
if (rtv != NULL)
{
*rtv = queue->front->data;
}
Node *pDel = queue->front;
queue->front = pDel->next;
if (queue->front == NULL)
{
queue->last = NULL;
}
free(pDel);
pDel = NULL;
return true;
}
void Show(QueueList queue)
{
Node *p = queue->front;
while (p != NULL)
{
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
int GetLength(QueueList queue)
{
int len = 0;
Node *p = queue->front;
while (p != NULL)
{
len++;
p = p->next;
}
return len;
}
bool IsEmpty(QueueList queue)
{
if (queue->front == NULL || queue->last == NULL)
{
return true;
}
return false;
}
void Clear(QueueList queue)
{
Destroy(queue);
}
void Destroy(QueueList queue)
{
Node *p =NULL;
while (queue->front != NULL)
{
p = queue->front;
queue->front = p->next;
free(p);
p =NULL;
}
queue->front = NULL;
queue->rear = NULL;
}