简介
上篇文章介绍了如何用数组实现Queue队列,本篇文章将简单介绍一下使用链表实现队列数据结构。同样和链表实现堆栈一样,因为使用的单向链表所以队列的Front指针只能指向链表头部的位置,而对于只需要添加操作的Rear指针可以使用链表尾部的位置。
因为实现步骤都差不多,一些要点也写在代码注释里面了所以这篇文章就不具体介绍思路了直接贴代码
代码实现
linked_list_queue.h头文件
#ifndef C_LINKED_LIST_QUEUE_H
#define C_LINKED_LIST_QUEUE_H
typedef struct QueueNode *NodePtr;
// 这里需要一个指向结构体的指针,所以需要具名结构
// 不然不好定义上面的结构体指针别名NodePtr
typedef struct QueueNode {
int data;
NodePtr next;
} QNode;
// 可以使用匿名结构,也就是不要LinkedListQueue这个结构体名称
typedef struct LinkedListQueue {
NodePtr front;
NodePtr rear;
} LLQueue, *LLQueuePtr;
void initLinkedListQueue(LLQueuePtr queue);
void linkedListEnqueue(LLQueuePtr queue, int item);
int linkedListDequeue(LLQueuePtr queue);
void linkedListQueueTest(void);
#endif //C_LINKED_LIST_QUEUE_H
linked_list_queue.c代码文件
#include "linked_list_queue.h"
#include <stdio.h>
#include <stdlib.h>
void initLinkedListQueue(LLQueuePtr queue) {
queue->front = NULL;
queue->rear = NULL;
}
void linkedListEnqueue(LLQueuePtr queue, int item) {
// 为结点申请内存空间
NodePtr p = (NodePtr) malloc(sizeof(QNode));
if (NULL == p) {
printf("内存空间申请失败!!!\n");
} else {
// 当什么都没做初始化的队列新入列一个元素时,设置头尾指针都指向第一个元素
if (queue->front == NULL) {
queue->front = p;
}
if (queue->rear == NULL) {
queue->rear = p;
} else {
// 如果此时Rear已经指向一个结点,那么需要将当前结点的Next指向新入列的结点p
queue->rear->next = p;
queue->rear = p;
}
p->data = item;
// 新入列的结点Next指向NULL
p->next = NULL;
}
}
int linkedListDequeue(LLQueuePtr queue) {
int ret = NULL;
if (NULL == queue->front) {
printf("this queue is empty\n");
} else {
// 前后都指向同一个位置说明此时队列里只剩下一个元素了
ret = queue->front->data;
NodePtr ptr = queue->front;
// 链表头将要被删除,此时队列Front指向下一个队列元素结点
queue->front = queue->front->next;
// 将上一个元素结点内存回收
free(ptr);
// 有一种情况需要移动Rear,那就是本次出列后队列为空的时候
if (NULL == queue->front) {
queue->rear = NULL;
}
}
return ret;
}
void linkedListQueueTest() {
LLQueue llQueue;
LLQueuePtr queue = &llQueue;
initLinkedListQueue(queue);
const int Size = 10;
printf("start enqueue: \n");
for (int i = 0; i < Size; ++i) {
int num = rand() % 101;
printf("this enqueue num is %d\n", num);
linkedListEnqueue(queue, num);
}
printf("start dequeue: \n");
for (int i = 0; i < Size; ++i) {
printf("this dequeue num is %d\n", linkedListDequeue(queue));
}
}
测试函数运行截图
总结
用链表来处理队列真的很方便,也处理堆栈一样只要内存空间足够多就可以一直插入队列。同时出列操作也比用数组存储来的方便。