C 语言队列与链表的结合应用
前言
在计算机科学和软件工程领域,数据结构的选择和组合往往决定了程序的性能和可扩展性。队列(Queue)和链表(Linked List)作为两种基础而重要的数据结构,各自具有独特的优势和适用场景。队列遵循先进先出(FIFO)的原则,适用于任务调度、数据缓冲等场景;而链表则提供了动态内存分配和高效的插入删除操作。
当这两种数据结构有机结合时,能够产生更加强大和灵活的数据处理能力。链表实现的队列不仅继承了队列的 FIFO 特性,还具备了链表动态扩展、内存高效利用等优点。这种结合在实际项目开发中有着广泛的应用,从操作系统的进程调度到网络编程的数据包处理,从内存管理到算法设计,都能看到链表队列的身影。
本文将深入探讨 C 语言中队列与链表的结合应用,从基础概念到高级技巧,从理论分析到实践代码,为读者提供一套完整的学习和应用指南。无论您是 C 语言初学者还是有一定经验的开发者,通过阅读本文,您都将深入理解链表队列的工作原理,掌握其实现技巧,并能够在实际项目中灵活运用。
目录
1. 队列与链表结合的基本概念
1.1 为什么选择链表实现队列
数组队列的局限性:
传统的数组实现队列存在以下问题:
-
固定大小:需要预先分配固定大小的内存空间
-
假溢出:可能出现队列未满但无法插入的情况
-
动态扩容复杂:扩容时需要大量数据移动
链表队列的优势:
相比数组队列,链表实现的队列具有显著优势:
-
动态扩展:不需要预先分配内存,可根据需要动态增长
-
内存高效:只使用实际需要的内存空间
-
操作高效:插入和删除操作时间复杂度为 O (1)
-
无假溢出问题:不存在数组队列的假溢出问题
1.2 链表队列的基本结构
单链表队列结构:
// 链表队列的基本结构
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
// 链表节点结构
typedef struct QueueNode {
int data; // 数据域
struct QueueNode *next; // 指针域,指向下一个节点
} QueueNode;
// 队列管理结构
typedef struct {
QueueNode *front; // 队头指针
QueueNode *rear; // 队尾指针
int size; // 队列大小
int max_size; // 最大容量(可选)
} LinkedListQueue;
结构说明:
-
QueueNode:链表的基本节点,包含数据域和指针域
-
LinkedListQueue:队列的管理结构,包含队头指针、队尾指针和队列大小信息
-
front:指向队列的第一个元素,用于出队操作
-
rear:指向队列的最后一个元素,用于入队操作
1.3 链表队列的操作特性
基本操作:
-
入队(Enqueue):在链表尾部插入新节点
-
出队(Dequeue):从链表头部删除节点
-
查看队头(Front):获取队头元素但不删除
-
查看队尾(Rear):获取队尾元素但不删除
-
判空(IsEmpty):判断队列是否为空
-
获取大小(Size):获取队列中元素的数量
操作时间复杂度:
-
入队操作:O (1)
-
出队操作:O (1)
-
查看队头 / 队尾:O (1)
-
判空 / 获取大小:O (1)
1.4 链表队列的应用场景
适合使用链表队列的场景:
-
数据量不确定:无法预先知道数据的数量
-
频繁插入删除:需要经常进行入队和出队操作
-
内存受限环境:需要高效利用内存空间
-
实时系统:对时间复杂度要求较高的场景
典型应用领域:
-
操作系统:进程调度、内存管理、设备驱动
-
网络编程:数据包处理、消息队列
-
数据库:查询优化、事务处理
-
算法设计:广度优先搜索、动态规划
2. 链表队列的基础实现
2.1 节点创建与队列初始化
创建新节点:
// 创建新节点
QueueNode* create_queue_node(int data) {
QueueNode *new_node = (QueueNode *)malloc(sizeof(QueueNode));
if (new_node == NULL) {
printf("内存分配失败n");
return NULL;
}
new_node->data = data;
new_node->next = NULL;
return new_node;
}
// 初始化队列
LinkedListQueue* init_linked_list_queue(int max_size) {
LinkedListQueue *queue = (LinkedListQueue *)malloc(sizeof(LinkedListQueue));
if (queue == NULL) {
printf("内存分配失败n");
return NULL;
}
queue->front = NULL;
queue->rear = NULL;
queue->size = 0;
queue->max_size = max_size;
return queue;
}
2.2 入队操作实现
基本入队操作:
// 入队操作
int enqueue(LinkedListQueue *queue, int data) {
if (queue == NULL) {
printf("队列未初始化n");
return -1;
}
// 检查容量限制
if (queue->max_size > 0 && queue->size >= queue->max_size) {
printf("队列已满n");
return -1;
}
QueueNode *new_node = create_queue_node(data);
if (new_node == NULL) {
return -1;
}
if (queue->rear == NULL) {
// 队列为空
queue->front = new_node;
queue->rear = new_node;
} else {
// 队列不为空
queue->rear->next = new_node;
queue->rear = new_node;
}
queue->size++;
return 0;
}
// 批量入队操作
int enqueue_batch(LinkedListQueue *queue, int *data_array, int count) {
if (queue == NULL || data_array == NULL || count <= 0) {
return -1;
}
// 检查容量限制
int remaining_space = queue->max_size > 0 ? (queue->max_size - queue->size) : count;
if (count > remaining_space) {
printf("队列空间不足,只能入队%d个元素n", remaining_space);
count = remaining_space;
}
QueueNode *first_new_node = NULL;
QueueNode *last_new_node = NULL;
// 创建新节点
for (int i = 0; i < count; i++) {
QueueNode *new_node = create_queue_node(data_array[i]);
if (new_node == NULL) {
// 清理已创建的节点
QueueNode *current = first_new_node;
while (current != NULL) {
QueueNode *temp = current;
current = current->next;
free(temp);
}
return i; // 返回已成功创建的节点数
}
if (first_new_node == NULL) {
first_new_node = new_node;
last_new_node = new_node;
} else {
last_new_node->next = new_node;
last_new_node = new_node;
}
}
// 将新节点插入队列
if (queue->rear == NULL) {
queue->front = first_new_node;
queue->rear = last_new_node;
} else {
queue->rear->next = first_new_node;
queue->rear = last_new_node;
}
queue->size += count;
return count;
}
2.3 出队操作实现
基本出队操作:
// 出队操作
int dequeue(LinkedListQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
printf("参数无效n");
return -1;
}
if (queue->size == 0) {
printf("队列为空n");
return -1;
}
QueueNode *temp = queue->front;
*data = temp->data;
queue->front = queue->front->next;
if (queue->front == NULL) {
queue->rear = NULL;
}
free(temp);
queue->size--;
return 0;
}
// 批量出队操作
int dequeue_batch(LinkedListQueue *queue, int *buffer, int count) {
if (queue == NULL || buffer == NULL || count <= 0) {
return -1;
}
// 检查可用元素数量
int available = queue->size;
if (count > available) {
printf("队列元素不足,只能出队%d个元素n", available);
count = available;
}
for (int i = 0; i < count; i++) {
buffer[i] = queue->front->data;
QueueNode *temp = queue->front;
queue->front = queue->front->next;
free(temp);
}
if (queue->front == NULL) {
queue->rear = NULL;
}
queue->size -= count;
return count;
}
2.4 辅助操作实现
队列辅助操作:
// 判断队列是否为空
bool is_queue_empty(LinkedListQueue *queue) {
return queue == NULL || queue->size == 0;
}
// 判断队列是否已满
bool is_queue_full(LinkedListQueue *queue) {
if (queue == NULL || queue->max_size <= 0) {
return false;
}
return queue->size >= queue->max_size;
}
// 获取队列大小
int get_queue_size(LinkedListQueue *queue) {
if (queue == NULL) {
return -1;
}
return queue->size;
}
// 获取队头元素
int get_queue_front(LinkedListQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
printf("参数无效n");
return -1;
}
if (queue->size == 0) {
printf("队列为空n");
return -1;
}
*data = queue->front->data;
return 0;
}
// 获取队尾元素
int get_queue_rear(LinkedListQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
printf("参数无效n");
return -1;
}
if (queue->size == 0) {
printf("队列为空n");
return -1;
}
*data = queue->rear->data;
return 0;
}
// 清空队列
void clear_queue(LinkedListQueue *queue) {
if (queue == NULL) {
return;
}
QueueNode *current = queue->front;
while (current != NULL) {
QueueNode *temp = current;
current = current->next;
free(temp);
}
queue->front = NULL;
queue->rear = NULL;
queue->size = 0;
}
// 销毁队列
void destroy_queue(LinkedListQueue *queue) {
if (queue == NULL) {
return;
}
clear_queue(queue);
free(queue);
}
// 打印队列
void print_queue(LinkedListQueue *queue) {
if (queue == NULL || queue->size == 0) {
printf("队列为空n");
return;
}
printf("队列元素: ");
QueueNode *current = queue->front;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("n");
}
2.5 完整示例程序
链表队列完整示例:
// 链表队列完整示例程序
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 链表节点结构
typedef struct QueueNode {
int data;
struct QueueNode *next;
} QueueNode;
// 队列管理结构
typedef struct {
QueueNode *front;
QueueNode *rear;
int size;
int max_size;
} LinkedListQueue;
// 创建新节点
QueueNode* create_queue_node(int data) {
QueueNode *new_node = (QueueNode *)malloc(sizeof(QueueNode));
if (new_node == NULL) {
printf("内存分配失败n");
return NULL;
}
new_node->data = data;
new_node->next = NULL;
return new_node;
}
// 初始化队列
LinkedListQueue* init_linked_list_queue(int max_size) {
LinkedListQueue *queue = (LinkedListQueue *)malloc(sizeof(LinkedListQueue));
if (queue == NULL) {
printf("内存分配失败n");
return NULL;
}
queue->front = NULL;
queue->rear = NULL;
queue->size = 0;
queue->max_size = max_size;
return queue;
}
// 入队操作
int enqueue(LinkedListQueue *queue, int data) {
if (queue == NULL) {
printf("队列未初始化n");
return -1;
}
if (queue->max_size > 0 && queue->size >= queue->max_size) {
printf("队列已满n");
return -1;
}
QueueNode *new_node = create_queue_node(data);
if (new_node == NULL) {
return -1;
}
if (queue->rear == NULL) {
queue->front = new_node;
queue->rear = new_node;
} else {
queue->rear->next = new_node;
queue->rear = new_node;
}
queue->size++;
return 0;
}
// 出队操作
int dequeue(LinkedListQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
printf("参数无效n");
return -1;
}
if (queue->size == 0) {
printf("队列为空n");
return -1;
}
QueueNode *temp = queue->front;
*data = temp->data;
queue->front = queue->front->next;
if (queue->front == NULL) {
queue->rear = NULL;
}
free(temp);
queue->size--;
return 0;
}
// 打印队列
void print_queue(LinkedListQueue *queue) {
if (queue == NULL || queue->size == 0) {
printf("队列为空n");
return;
}
printf("队列元素: ");
QueueNode *current = queue->front;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("n");
}
// 销毁队列
void destroy_queue(LinkedListQueue *queue) {
if (queue == NULL) {
return;
}
QueueNode *current = queue->front;
while (current != NULL) {
QueueNode *temp = current;
current = current->next;
free(temp);
}
free(queue);
}
// 主函数示例
int main() {
// 初始化队列,最大容量为10
LinkedListQueue *queue = init_linked_list_queue(10);
if (queue == NULL) {
return 1;
}
// 入队操作
for (int i = 1; i <= 5; i++) {
enqueue(queue, i);
}
printf("入队5个元素后: ");
print_queue(queue);
// 出队操作
int data;
dequeue(queue, &data);
printf("出队元素: %dn", data);
printf("出队后队列: ");
print_queue(queue);
// 入队更多元素
for (int i = 6; i <= 10; i++) {
enqueue(queue, i);
}
printf("入队更多元素后: ");
print_queue(queue);
// 尝试入队第11个元素(超出容量)
if (enqueue(queue, 11) != 0) {
printf("入队第11个元素失败n");
}
// 批量出队
int buffer[5];
int count = dequeue_batch(queue, buffer, 5);
printf("批量出队%d个元素: ", count);
for (int i = 0; i < count; i++) {
printf("%d ", buffer[i]);
}
printf("n");
printf("批量出队后队列: ");
print_queue(queue);
// 销毁队列
destroy_queue(queue);
return 0;
}
3. 链表队列的高级特性
3.1 动态扩容机制
自动扩容实现:
// 链表队列的动态扩容机制
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 动态扩容的链表队列
typedef struct {
QueueNode *front;
QueueNode *rear;
int size;
int capacity; // 当前容量
float load_factor; // 负载因子
} DynamicLinkedListQueue;
// 初始化动态扩容队列
DynamicLinkedListQueue* init_dynamic_queue(int initial_capacity, float load_factor) {
DynamicLinkedListQueue *queue = (DynamicLinkedListQueue *)malloc(sizeof(DynamicLinkedListQueue));
if (queue == NULL) {
return NULL;
}
queue->front = NULL;
queue->rear = NULL;
queue->size = 0;
queue->capacity = initial_capacity > 0 ? initial_capacity : 10;
queue->load_factor = load_factor > 0 ? load_factor : 0.75f;
return queue;
}
// 检查是否需要扩容
bool need_resize(DynamicLinkedListQueue *queue) {
if (queue == NULL || queue->capacity <= 0) {
return false;
}
float current_load = (float)queue->size / queue->capacity;
return current_load >= queue->load_factor;
}
// 动态扩容
int resize_queue(DynamicLinkedListQueue *queue) {
if (queue == NULL) {
return -1;
}
// 扩容为原来的2倍
int new_capacity = queue->capacity * 2;
printf("队列扩容: %d -> %dn", queue->capacity, new_capacity);
queue->capacity = new_capacity;
return 0;
}
// 动态扩容入队操作
int dynamic_enqueue(DynamicLinkedListQueue *queue, int data) {
if (queue == NULL) {
return -1;
}
// 检查是否需要扩容
if (need_resize(queue)) {
resize_queue(queue);
}
QueueNode *new_node = create_queue_node(data);
if (new_node == NULL) {
return -1;
}
if (queue->rear == NULL) {
queue->front = new_node;
queue->rear = new_node;
} else {
queue->rear->next = new_node;
queue->rear = new_node;
}
queue->size++;
return 0;
}
3.2 内存池优化
内存池管理:
// 链表队列的内存池优化
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MEMORY_POOL_SIZE 1000
// 内存池结构
typedef struct {
QueueNode *free_list;
int node_count;
int free_count;
} MemoryPool;
// 初始化内存池
MemoryPool* init_memory_pool(int size) {
MemoryPool *pool = (MemoryPool *)malloc(sizeof(MemoryPool));
if (pool == NULL) {
return NULL;
}
pool->free_list = NULL;
pool->node_count = 0;
pool->free_count = 0;
// 预分配节点
for (int i = 0; i < size; i++) {
QueueNode *node = (QueueNode *)malloc(sizeof(QueueNode));
if (node == NULL) {
// 清理已分配的节点
while (pool->free_list != NULL) {
QueueNode *temp = pool->free_list;
pool->free_list = pool->free_list->next;
free(temp);
}
free(pool);
return NULL;
}
node->next = pool->free_list;
pool->free_list = node;
pool->node_count++;
pool->free_count++;
}
return pool;
}
// 从内存池分配节点
QueueNode* pool_alloc_node(MemoryPool *pool, int data) {
if (pool == NULL) {
return create_queue_node(data);
}
if (pool->free_list != NULL) {
QueueNode *node = pool->free_list;
pool->free_list = pool->free_list->next;
pool->free_count--;
node->data = data;
node->next = NULL;
return node;
}
// 内存池为空,直接分配
QueueNode *node = create_queue_node(data);
if (node != NULL) {
pool->node_count++;
}
return node;
}
// 将节点归还给内存池
void pool_free_node(MemoryPool *pool, QueueNode *node) {
if (pool == NULL || node == NULL) {
free(node);
return;
}
node->next = pool->free_list;
pool->free_list = node;
pool->free_count++;
}
// 使用内存池的队列
typedef struct {
QueueNode *front;
QueueNode *rear;
int size;
MemoryPool *pool;
} PooledLinkedListQueue;
// 初始化带内存池的队列
PooledLinkedListQueue* init_pooled_queue(int pool_size) {
PooledLinkedListQueue *queue = (PooledLinkedListQueue *)malloc(sizeof(PooledLinkedListQueue));
if (queue == NULL) {
return NULL;
}
queue->front = NULL;
queue->rear = NULL;
queue->size = 0;
queue->pool = init_memory_pool(pool_size);
return queue;
}
// 带内存池的入队操作
int pooled_enqueue(PooledLinkedListQueue *queue, int data) {
if (queue == NULL) {
return -1;
}
QueueNode *new_node = pool_alloc_node(queue->pool, data);
if (new_node == NULL) {
return -1;
}
if (queue->rear == NULL) {
queue->front = new_node;
queue->rear = new_node;
} else {
queue->rear->next = new_node;
queue->rear = new_node;
}
queue->size++;
return 0;
}
// 带内存池的出队操作
int pooled_dequeue(PooledLinkedListQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
return -1;
}
if (queue->size == 0) {
return -1;
}
QueueNode *temp = queue->front;
*data = temp->data;
queue->front = queue->front->next;
if (queue->front == NULL) {
queue->rear = NULL;
}
pool_free_node(queue->pool, temp);
queue->size--;
return 0;
}
3.3 线程安全机制
线程安全的链表队列:
// 线程安全的链表队列
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
#include <stdatomic.h>
// 线程安全队列结构
typedef struct {
QueueNode *front;
QueueNode *rear;
atomic_int size;
pthread_mutex_t mutex;
pthread_cond_t not_full;
pthread_cond_t not_empty;
int max_size;
bool stopped;
} ThreadSafeLinkedListQueue;
// 初始化线程安全队列
ThreadSafeLinkedListQueue* init_thread_safe_queue(int max_size) {
ThreadSafeLinkedListQueue *queue = (ThreadSafeLinkedListQueue *)malloc(sizeof(ThreadSafeLinkedListQueue));
if (queue == NULL) {
return NULL;
}
queue->front = NULL;
queue->rear = NULL;
atomic_init(&queue->size, 0);
queue->max_size = max_size;
queue->stopped = false;
pthread_mutex_init(&queue->mutex, NULL);
pthread_cond_init(&queue->not_full, NULL);
pthread_cond_init(&queue->not_empty, NULL);
return queue;
}
// 线程安全入队操作
int thread_safe_enqueue(ThreadSafeLinkedListQueue *queue, int data) {
if (queue == NULL) {
return -1;
}
pthread_mutex_lock(&queue->mutex);
// 等待队列不满且未停止
while (!queue->stopped && queue->max_size > 0 && atomic_load(&queue->size) >= queue->max_size) {
pthread_cond_wait(&queue->not_full, &queue->mutex);
}
if (queue->stopped) {
pthread_mutex_unlock(&queue->mutex);
return -1;
}
QueueNode *new_node = create_queue_node(data);
if (new_node == NULL) {
pthread_mutex_unlock(&queue->mutex);
return -1;
}
if (queue->rear == NULL) {
queue->front = new_node;
queue->rear = new_node;
} else {
queue->rear->next = new_node;
queue->rear = new_node;
}
atomic_fetch_add(&queue->size, 1);
pthread_cond_signal(&queue->not_empty);
pthread_mutex_unlock(&queue->mutex);
return 0;
}
// 线程安全出队操作
int thread_safe_dequeue(ThreadSafeLinkedListQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
return -1;
}
pthread_mutex_lock(&queue->mutex);
// 等待队列不空且未停止
while (!queue->stopped && atomic_load(&queue->size) == 0) {
pthread_cond_wait(&queue->not_empty, &queue->mutex);
}
if (queue->stopped) {
pthread_mutex_unlock(&queue->mutex);
return -1;
}
QueueNode *temp = queue->front;
*data = temp->data;
queue->front = queue->front->next;
if (queue->front == NULL) {
queue->rear = NULL;
}
free(temp);
atomic_fetch_sub(&queue->size, 1);
pthread_cond_signal(&queue->not_full);
pthread_mutex_unlock(&queue->mutex);
return 0;
}
// 停止线程安全队列
void stop_thread_safe_queue(ThreadSafeLinkedListQueue *queue) {
if (queue == NULL) {
return;
}
pthread_mutex_lock(&queue->mutex);
queue->stopped = true;
pthread_cond_broadcast(&queue->not_full);
pthread_cond_broadcast(&queue->not_empty);
pthread_mutex_unlock(&queue->mutex);
}
// 销毁线程安全队列
void destroy_thread_safe_queue(ThreadSafeLinkedListQueue *queue) {
if (queue == NULL) {
return;
}
stop_thread_safe_queue(queue);
pthread_mutex_lock(&queue->mutex);
QueueNode *current = queue->front;
while (current != NULL) {
QueueNode *temp = current;
current = current->next;
free(temp);
}
pthread_mutex_unlock(&queue->mutex);
pthread_mutex_destroy(&queue->mutex);
pthread_cond_destroy(&queue->not_full);
pthread_cond_destroy(&queue->not_empty);
free(queue);
}
4. 双向链表队列的实现
4.1 双向链表队列结构
双向链表节点定义:
// 双向链表队列实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 双向链表节点
typedef struct DoublyQueueNode {
int data;
struct DoublyQueueNode *prev;
struct DoublyQueueNode *next;
} DoublyQueueNode;
// 双向链表队列
typedef struct {
DoublyQueueNode *front;
DoublyQueueNode *rear;
int size;
int max_size;
} DoublyLinkedListQueue;
// 创建双向链表节点
DoublyQueueNode* create_doubly_node(int data) {
DoublyQueueNode *new_node = (DoublyQueueNode *)malloc(sizeof(DoublyQueueNode));
if (new_node == NULL) {
printf("内存分配失败n");
return NULL;
}
new_node->data = data;
new_node->prev = NULL;
new_node->next = NULL;
return new_node;
}
// 初始化双向链表队列
DoublyLinkedListQueue* init_doubly_queue(int max_size) {
DoublyLinkedListQueue *queue = (DoublyLinkedListQueue *)malloc(sizeof(DoublyLinkedListQueue));
if (queue == NULL) {
printf("内存分配失败n");
return NULL;
}
queue->front = NULL;
queue->rear = NULL;
queue->size = 0;
queue->max_size = max_size;
return queue;
}
4.2 双向链表队列的操作实现
双向链表队列操作:
// 从队尾入队
int doubly_enqueue_rear(DoublyLinkedListQueue *queue, int data) {
if (queue == NULL) {
printf("队列未初始化n");
return -1;
}
if (queue->max_size > 0 && queue->size >= queue->max_size) {
printf("队列已满n");
return -1;
}
DoublyQueueNode *new_node = create_doubly_node(data);
if (new_node == NULL) {
return -1;
}
if (queue->rear == NULL) {
queue->front = new_node;
queue->rear = new_node;
} else {
new_node->prev = queue->rear;
queue->rear->next = new_node;
queue->rear = new_node;
}
queue->size++;
return 0;
}
// 从队头入队
int doubly_enqueue_front(DoublyLinkedListQueue *queue, int data) {
if (queue == NULL) {
printf("队列未初始化n");
return -1;
}
if (queue->max_size > 0 && queue->size >= queue->max_size) {
printf("队列已满n");
return -1;
}
DoublyQueueNode *new_node = create_doubly_node(data);
if (new_node == NULL) {
return -1;
}
if (queue->front == NULL) {
queue->front = new_node;
queue->rear = new_node;
} else {
new_node->next = queue->front;
queue->front->prev = new_node;
queue->front = new_node;
}
queue->size++;
return 0;
}
// 从队头出队
int doubly_dequeue_front(DoublyLinkedListQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
printf("参数无效n");
return -1;
}
if (queue->size == 0) {
printf("队列为空n");
return -1;
}
DoublyQueueNode *temp = queue->front;
*data = temp->data;
queue->front = queue->front->next;
if (queue->front == NULL) {
queue->rear = NULL;
} else {
queue->front->prev = NULL;
}
free(temp);
queue->size--;
return 0;
}
// 从队尾出队
int doubly_dequeue_rear(DoublyLinkedListQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
printf("参数无效n");
return -1;
}
if (queue->size == 0) {
printf("队列为空n");
return -1;
}
DoublyQueueNode *temp = queue->rear;
*data = temp->data;
queue->rear = queue->rear->prev;
if (queue->rear == NULL) {
queue->front = NULL;
} else {
queue->rear->next = NULL;
}
free(temp);
queue->size--;
return 0;
}
4.3 双向链表队列的优势
双向链表队列的特点:
// 双向链表队列的优势演示
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// 性能测试函数
void test_doubly_queue_performance() {
const int TEST_SIZE = 100000;
DoublyLinkedListQueue *queue = init_doubly_queue(0);
clock_t start_time = clock();
// 测试队尾入队
for (int i = 0; i < TEST_SIZE; i++) {
doubly_enqueue_rear(queue, i);
}
printf("队尾入队%d个元素耗时: %.3f秒n", TEST_SIZE,
(double)(clock() - start_time) / CLOCKS_PER_SEC);
// 测试队头出队
start_time = clock();
int data;
for (int i = 0; i < TEST_SIZE; i++) {
doubly_dequeue_front(queue, &data);
}
printf("队头出队%d个元素耗时: %.3f秒n", TEST_SIZE,
(double)(clock() - start_time) / CLOCKS_PER_SEC);
// 测试队头入队
start_time = clock();
for (int i = 0; i < TEST_SIZE; i++) {
doubly_enqueue_front(queue, i);
}
printf("队头入队%d个元素耗时: %.3f秒n", TEST_SIZE,
(double)(clock() - start_time) / CLOCKS_PER_SEC);
// 测试队尾出队
start_time = clock();
for (int i = 0; i < TEST_SIZE; i++) {
doubly_dequeue_rear(queue, &data);
}
printf("队尾出队%d个元素耗时: %.3f秒n", TEST_SIZE,
(double)(clock() - start_time) / CLOCKS_PER_SEC);
destroy_doubly_queue(queue);
}
// 双向链表队列的应用场景
void demonstrate_doubly_queue_applications() {
// 场景1:双端队列(Deque)实现
DoublyLinkedListQueue *deque = init_doubly_queue(0);
// 前端插入
doubly_enqueue_front(deque, 1);
doubly_enqueue_front(deque, 2);
// 后端插入
doubly_enqueue_rear(deque, 3);
doubly_enqueue_rear(deque, 4);
printf("双端队列内容: ");
print_doubly_queue(deque);
// 场景2:实现栈和队列的混合操作
int data;
doubly_dequeue_front(deque, &data); // 队列操作
printf("队头出队: %dn", data);
doubly_dequeue_rear(deque, &data); // 栈操作
printf("队尾出队: %dn", data);
destroy_doubly_queue(deque);
}
5. 循环链表队列的实现
5.1 循环链表队列结构
循环链表队列定义:
// 循环链表队列实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 循环链表节点
typedef struct CircularQueueNode {
int data;
struct CircularQueueNode *next;
} CircularQueueNode;
// 循环链表队列
typedef struct {
CircularQueueNode *rear; // 指向队尾节点
int size;
int max_size;
} CircularLinkedListQueue;
// 创建循环链表节点
CircularQueueNode* create_circular_node(int data) {
CircularQueueNode *new_node = (CircularQueueNode *)malloc(sizeof(CircularQueueNode));
if (new_node == NULL) {
printf("内存分配失败n");
return NULL;
}
new_node->data = data;
new_node->next = NULL;
return new_node;
}
// 初始化循环链表队列
CircularLinkedListQueue* init_circular_queue(int max_size) {
CircularLinkedListQueue *queue = (CircularLinkedListQueue *)malloc(sizeof(CircularLinkedListQueue));
if (queue == NULL) {
printf("内存分配失败n");
return NULL;
}
queue->rear = NULL;
queue->size = 0;
queue->max_size = max_size;
return queue;
}
5.2 循环链表队列的操作实现
循环链表队列操作:
// 入队操作
int circular_enqueue(CircularLinkedListQueue *queue, int data) {
if (queue == NULL) {
printf("队列未初始化n");
return -1;
}
if (queue->max_size > 0 && queue->size >= queue->max_size) {
printf("队列已满n");
return -1;
}
CircularQueueNode *new_node = create_circular_node(data);
if (new_node == NULL) {
return -1;
}
if (queue->rear == NULL) {
// 队列为空
new_node->next = new_node; // 指向自身
queue->rear = new_node;
} else {
new_node->next = queue->rear->next;
queue->rear->next = new_node;
queue->rear = new_node;
}
queue->size++;
return 0;
}
// 出队操作
int circular_dequeue(CircularLinkedListQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
printf("参数无效n");
return -1;
}
if (queue->size == 0) {
printf("队列为空n");
return -1;
}
CircularQueueNode *front = queue->rear->next;
*data = front->data;
if (queue->size == 1) {
// 只有一个节点
queue->rear = NULL;
} else {
queue->rear->next = front->next;
}
free(front);
queue->size--;
return 0;
}
// 获取队头元素
int circular_get_front(CircularLinkedListQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
return -1;
}
if (queue->size == 0) {
return -1;
}
*data = queue->rear->next->data;
return 0;
}
// 获取队尾元素
int circular_get_rear(CircularLinkedListQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
return -1;
}
if (queue->size == 0) {
return -1;
}
*data = queue->rear->data;
return 0;
}
// 打印循环队列
void print_circular_queue(CircularLinkedListQueue *queue) {
if (queue == NULL || queue->size == 0) {
printf("队列为空n");
return;
}
printf("循环队列元素: ");
CircularQueueNode *current = queue->rear->next;
for (int i = 0; i < queue->size; i++) {
printf("%d ", current->data);
current = current->next;
}
printf("n");
}
5.3 循环链表队列的应用
约瑟夫环问题:
// 约瑟夫环问题的循环链表队列实现
#include <stdio.h>
#include <stdlib.h>
// 约瑟夫环函数
int josephus_problem(int n, int k) {
if (n <= 0 || k <= 0) {
return -1;
}
CircularLinkedListQueue *queue = init_circular_queue(0);
// 初始化队列
for (int i = 1; i <= n; i++) {
circular_enqueue(queue, i);
}
int count = 0;
int result = -1;
while (queue->size > 1) {
int person;
circular_dequeue(queue, &person);
count++;
if (count == k) {
// 淘汰第k个人
printf("淘汰: %dn", person);
count = 0;
} else {
// 重新入队
circular_enqueue(queue, person);
}
}
// 获取最后一个人
if (queue->size == 1) {
circular_dequeue(queue, &result);
}
destroy_circular_queue(queue);
return result;
}
// 测试约瑟夫环
void test_josephus_problem() {
int n = 7; // 7个人
int k = 3; // 每3个人淘汰一个
printf("约瑟夫环问题: %d个人,每%d个淘汰一个n", n, k);
int winner = josephus_problem(n, k);
printf("最后的胜利者是: %dn", winner);
}
6. 优先级链表队列
6.1 优先级队列结构
优先级队列定义:
// 优先级链表队列实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 优先级队列节点
typedef struct PriorityQueueNode {
int data;
int priority; // 优先级,值越小优先级越高
struct PriorityQueueNode *next;
} PriorityQueueNode;
// 优先级队列
typedef struct {
PriorityQueueNode *front;
int size;
int max_size;
} PriorityLinkedListQueue;
// 创建优先级节点
PriorityQueueNode* create_priority_node(int data, int priority) {
PriorityQueueNode *new_node = (PriorityQueueNode *)malloc(sizeof(PriorityQueueNode));
if (new_node == NULL) {
printf("内存分配失败n");
return NULL;
}
new_node->data = data;
new_node->priority = priority;
new_node->next = NULL;
return new_node;
}
// 初始化优先级队列
PriorityLinkedListQueue* init_priority_queue(int max_size) {
PriorityLinkedListQueue *queue = (PriorityLinkedListQueue *)malloc(sizeof(PriorityLinkedListQueue));
if (queue == NULL) {
printf("内存分配失败n");
return NULL;
}
queue->front = NULL;
queue->size = 0;
queue->max_size = max_size;
return queue;
}
6.2 优先级队列操作实现
优先级队列操作:
// 入队操作(按优先级插入)
int priority_enqueue(PriorityLinkedListQueue *queue, int data, int priority) {
if (queue == NULL) {
printf("队列未初始化n");
return -1;
}
if (queue->max_size > 0 && queue->size >= queue->max_size) {
printf("队列已满n");
return -1;
}
PriorityQueueNode *new_node = create_priority_node(data, priority);
if (new_node == NULL) {
return -1;
}
// 队列为空或新节点优先级最高
if (queue->front == NULL || priority < queue->front->priority) {
new_node->next = queue->front;
queue->front = new_node;
} else {
// 找到合适的插入位置
PriorityQueueNode *current = queue->front;
while (current->next != NULL && current->next->priority <= priority) {
current = current->next;
}
new_node->next = current->next;
current->next = new_node;
}
queue->size++;
return 0;
}
// 出队操作(取出优先级最高的元素)
int priority_dequeue(PriorityLinkedListQueue *queue, int *data, int *priority) {
if (queue == NULL || data == NULL || priority == NULL) {
printf("参数无效n");
return -1;
}
if (queue->size == 0) {
printf("队列为空n");
return -1;
}
PriorityQueueNode *temp = queue->front;
*data = temp->data;
*priority = temp->priority;
queue->front = queue->front->next;
free(temp);
queue->size--;
return 0;
}
// 按优先级范围出队
int priority_dequeue_by_level(PriorityLinkedListQueue *queue, int max_priority,
int *buffer, int *priorities, int max_count) {
if (queue == NULL || buffer == NULL || priorities == NULL || max_count <= 0) {
return -1;
}
int count = 0;
PriorityQueueNode **prev_ptr = &queue->front;
while (*prev_ptr != NULL && count < max_count) {
PriorityQueueNode *current = *prev_ptr;
if (current->priority <= max_priority) {
buffer[count] = current->data;
priorities[count] = current->priority;
count++;
// 移除节点
*prev_ptr = current->next;
free(current);
queue->size--;
} else {
prev_ptr = ¤t->next;
}
}
return count;
}
// 打印优先级队列
void print_priority_queue(PriorityLinkedListQueue *queue) {
if (queue == NULL || queue->size == 0) {
printf("队列为空n");
return;
}
printf("优先级队列元素: ");
PriorityQueueNode *current = queue->front;
while (current != NULL) {
printf("(%d:%d) ", current->data, current->priority);
current = current->next;
}
printf("n");
}
6.3 优先级队列的应用
任务调度系统:
// 优先级队列应用:任务调度系统
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// 任务类型
typedef enum {
TASK_TYPE_LOW,
TASK_TYPE_NORMAL,
TASK_TYPE_HIGH,
TASK_TYPE_URGENT
} TaskType;
// 任务结构
typedef struct {
int id;
char name[50];
TaskType type;
time_t create_time;
void (*execute)(void*);
void* arg;
} Task;
// 任务调度器
typedef struct {
PriorityLinkedListQueue *task_queue;
} TaskScheduler;
// 任务优先级映射
int task_type_to_priority(TaskType type) {
switch (type) {
case TASK_TYPE_LOW: return 4;
case TASK_TYPE_NORMAL: return 3;
case TASK_TYPE_HIGH: return 2;
case TASK_TYPE_URGENT: return 1;
default: return 3;
}
}
// 创建任务
Task* create_task(int id, const char *name, TaskType type,
void (*execute)(void*), void* arg) {
Task *task = (Task *)malloc(sizeof(Task));
if (task == NULL) {
return NULL;
}
task->id = id;
strncpy(task->name, name, sizeof(task->name) - 1);
task->type = type;
task->create_time = time(NULL);
task->execute = execute;
task->arg = arg;
return task;
}
// 初始化任务调度器
TaskScheduler* init_task_scheduler() {
TaskScheduler *scheduler = (TaskScheduler *)malloc(sizeof(TaskScheduler));
if (scheduler == NULL) {
return NULL;
}
scheduler->task_queue = init_priority_queue(100);
if (scheduler->task_queue == NULL) {
free(scheduler);
return NULL;
}
return scheduler;
}
// 添加任务到调度器
int scheduler_add_task(TaskScheduler *scheduler, Task *task) {
if (scheduler == NULL || task == NULL) {
return -1;
}
int priority = task_type_to_priority(task->type);
return priority_enqueue(scheduler->task_queue, (int)(intptr_t)task, priority);
}
// 执行下一个任务
int scheduler_execute_next_task(TaskScheduler *scheduler) {
if (scheduler == NULL) {
return -1;
}
int task_ptr, priority;
if (priority_dequeue(scheduler->task_queue, &task_ptr, &priority) != 0) {
return -1;
}
Task *task = (Task *)(intptr_t)task_ptr;
printf("执行任务: %s (ID: %d, 优先级: %d)n",
task->name, task->id, priority);
if (task->execute != NULL) {
task->execute(task->arg);
}
free(task);
return 0;
}
// 示例任务函数
void print_message_task(void *arg) {
char *message = (char *)arg;
printf("任务执行结果: %sn", message);
}
void calculate_task(void *arg) {
int *numbers = (int *)arg;
int result = numbers[0] + numbers[1];
printf("计算结果: %d + %d = %dn", numbers[0], numbers[1], result);
free(numbers);
}
// 测试任务调度器
void test_task_scheduler() {
TaskScheduler *scheduler = init_task_scheduler();
if (scheduler == NULL) {
return;
}
// 添加不同优先级的任务
scheduler_add_task(scheduler, create_task(1, "系统备份", TASK_TYPE_URGENT,
print_message_task, "系统备份完成"));
scheduler_add_task(scheduler, create_task(2, "数据清理", TASK_TYPE_LOW,
print_message_task, "数据清理完成"));
scheduler_add_task(scheduler, create_task(3, "用户认证", TASK_TYPE_HIGH,
print_message_task, "用户认证通过"));
scheduler_add_task(scheduler, create_task(4, "邮件发送", TASK_TYPE_NORMAL,
print_message_task, "邮件发送成功"));
// 添加计算任务
int *numbers = (int *)malloc(2 * sizeof(int));
numbers[0] = 10;
numbers[1] = 20;
scheduler_add_task(scheduler, create_task(5, "数值计算", TASK_TYPE_HIGH,
calculate_task, numbers));
printf("任务调度开始...n");
while (scheduler->task_queue->size > 0) {
scheduler_execute_next_task(scheduler);
}
destroy_priority_queue(scheduler->task_queue);
free(scheduler);
}
7. 链表队列在实际项目中的应用
7.1 操作系统中的应用
进程调度队列:
// 链表队列在操作系统进程调度中的应用
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#define MAX_PROCESSES 100
// 进程状态
typedef enum {
PROCESS_NEW,
PROCESS_READY,
PROCESS_RUNNING,
PROCESS_BLOCKED,
PROCESS_TERMINATED
} ProcessState;
// 进程优先级
typedef enum {
PRIORITY_LOW,
PRIORITY_NORMAL,
PRIORITY_HIGH,
PRIORITY_REAL_TIME
} ProcessPriority;
// 进程结构
typedef struct {
int pid; // 进程ID
char name[50]; // 进程名称
ProcessState state; // 进程状态
ProcessPriority priority; // 进程优先级
int burst_time; // 运行时间
int remaining_time; // 剩余时间
int arrival_time; // 到达时间
int start_time; // 开始时间
int finish_time; // 完成时间
int waiting_time; // 等待时间
int turnaround_time; // 周转时间
} Process;
// 多级反馈队列调度器
typedef struct {
PriorityLinkedListQueue *queues[4]; // 4个优先级队列
int current_time;
Process *running_process;
} MLFQ_Scheduler;
// 创建进程
Process* create_process(int pid, const char *name, ProcessPriority priority, int burst_time) {
Process *process = (Process *)malloc(sizeof(Process));
if (process == NULL) {
return NULL;
}
process->pid = pid;
strncpy(process->name, name, sizeof(process->name) - 1);
process->state = PROCESS_NEW;
process->priority = priority;
process->burst_time = burst_time;
process->remaining_time = burst_time;
process->arrival_time = time(NULL);
process->start_time = 0;
process->finish_time = 0;
process->waiting_time = 0;
process->turnaround_time = 0;
return process;
}
// 初始化多级反馈队列调度器
MLFQ_Scheduler* init_mlfq_scheduler() {
MLFQ_Scheduler *scheduler = (MLFQ_Scheduler *)malloc(sizeof(MLFQ_Scheduler));
if (scheduler == NULL) {
return NULL;
}
// 初始化4个优先级队列
for (int i = 0; i < 4; i++) {
scheduler->queues[i] = init_priority_queue(MAX_PROCESSES);
if (scheduler->queues[i] == NULL) {
// 清理已创建的队列
for (int j = 0; j < i; j++) {
destroy_priority_queue(scheduler->queues[j]);
}
free(scheduler);
return NULL;
}
}
scheduler->current_time = 0;
scheduler->running_process = NULL;
return scheduler;
}
// 添加进程到调度器
int mlfq_add_process(MLFQ_Scheduler *scheduler, Process *process) {
if (scheduler == NULL || process == NULL) {
return -1;
}
int priority = process->priority;
return priority_enqueue(scheduler->queues[priority], (int)(intptr_t)process, priority);
}
// 选择下一个要运行的进程
Process* mlfq_select_next_process(MLFQ_Scheduler *scheduler) {
if (scheduler == NULL) {
return NULL;
}
// 从高优先级队列开始查找
for (int i = 0; i < 4; i++) {
if (!is_priority_queue_empty(scheduler->queues[i])) {
int data, priority;
priority_dequeue(scheduler->queues[i], &data, &priority);
return (Process *)(intptr_t)data;
}
}
return NULL;
}
// 时间片轮转调度
void mlfq_time_slice(MLFQ_Scheduler *scheduler, int time_slice) {
if (scheduler == NULL || scheduler->running_process == NULL) {
return;
}
Process *process = scheduler->running_process;
// 运行一个时间片
int run_time = time_slice;
if (process->remaining_time < run_time) {
run_time = process->remaining_time;
}
scheduler->current_time += run_time;
process->remaining_time -= run_time;
if (process->remaining_time <= 0) {
// 进程完成
process->state = PROCESS_TERMINATED;
process->finish_time = scheduler->current_time;
process->turnaround_time = process->finish_time - process->arrival_time;
process->waiting_time = process->turnaround_time - process->burst_time;
printf("进程完成: %s (PID: %d), 周转时间: %d, 等待时间: %dn",
process->name, process->pid, process->turnaround_time, process->waiting_time);
free(process);
scheduler->running_process = NULL;
} else {
// 进程未完成,降低优先级(如果可能)
if (process->priority < PRIORITY_REAL_TIME) {
process->priority = (ProcessPriority)(process->priority + 1);
}
// 将进程重新加入队列
mlfq_add_process(scheduler, process);
scheduler->running_process = NULL;
}
}
// 运行调度器
void mlfq_run(MLFQ_Scheduler *scheduler) {
if (scheduler == NULL) {
return;
}
while (true) {
// 如果没有运行中的进程,选择下一个进程
if (scheduler->running_process == NULL) {
scheduler->running_process = mlfq_select_next_process(scheduler);
if (scheduler->running_process == NULL) {
// 所有队列都为空
break;
}
// 记录进程开始时间
if (scheduler->running_process->start_time == 0) {
scheduler->running_process->start_time = scheduler->current_time;
}
scheduler->running_process->state = PROCESS_RUNNING;
printf("开始运行进程: %s (PID: %d), 优先级: %dn",
scheduler->running_process->name,
scheduler->running_process->pid,
scheduler->running_process->priority);
}
// 确定时间片大小(高优先级进程时间片较小)
int time_slice;
switch (scheduler->running_process->priority) {
case PRIORITY_REAL_TIME: time_slice = 100; break;
case PRIORITY_HIGH: time_slice = 50; break;
case PRIORITY_NORMAL: time_slice = 20; break;
case PRIORITY_LOW: time_slice = 10; break;
default: time_slice = 20;
}
// 执行时间片轮转
mlfq_time_slice(scheduler, time_slice);
}
printf("所有进程执行完成n");
}
// 测试多级反馈队列调度器
void test_mlfq_scheduler() {
MLFQ_Scheduler *scheduler = init_mlfq_scheduler();
if (scheduler == NULL) {
return;
}
// 添加测试进程
mlfq_add_process(scheduler, create_process(1, "系统服务", PRIORITY_REAL_TIME, 150));
mlfq_add_process(scheduler, create_process(2, "文本编辑器", PRIORITY_NORMAL, 80));
mlfq_add_process(scheduler, create_process(3, "视频播放器", PRIORITY_HIGH, 200));
mlfq_add_process(scheduler, create_process(4, "文件下载", PRIORITY_LOW, 300));
mlfq_add_process(scheduler, create_process(5, "音乐播放器", PRIORITY_NORMAL, 120));
printf("多级反馈队列调度开始...n");
mlfq_run(scheduler);
// 清理资源
for (int i = 0; i < 4; i++) {
destroy_priority_queue(scheduler->queues[i]);
}
free(scheduler);
}
7.2 网络编程中的应用
网络数据包队列:
// 链表队列在网络编程中的应用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#define MAX_PACKET_SIZE 4096
#define MAX_QUEUE_SIZE 1000
// 网络数据包结构
typedef struct {
char data[MAX_PACKET_SIZE];
int length;
struct sockaddr_in client_addr;
socklen_t addr_len;
time_t timestamp;
} NetworkPacket;
// 网络数据包队列
typedef struct {
ThreadSafeLinkedListQueue *receive_queue;
ThreadSafeLinkedListQueue *send_queue;
int server_fd;
pthread_t receive_thread;
pthread_t worker_thread;
pthread_t send_thread;
bool running;
} NetworkServer;
// 接收线程函数
void* network_receive_thread(void *arg) {
NetworkServer *server = (NetworkServer *)arg;
while (server->running) {
NetworkPacket *packet = (NetworkPacket *)malloc(sizeof(NetworkPacket));
if (packet == NULL) {
sleep(1);
continue;
}
packet->addr_len = sizeof(packet->client_addr);
packet->length = recvfrom(server->server_fd, packet->data, MAX_PACKET_SIZE, 0,
(struct sockaddr *)&packet->client_addr, &packet->addr_len);
if (packet->length > 0) {
packet->timestamp = time(NULL);
thread_safe_enqueue(server->receive_queue, (int)(intptr_t)packet);
} else {
free(packet);
sleep(1);
}
}
return NULL;
}
// 工作线程函数
void* network_worker_thread(void *arg) {
NetworkServer *server = (NetworkServer *)arg;
while (server->running) {
int packet_ptr;
if (thread_safe_dequeue(server->receive_queue, &packet_ptr) != 0) {
sleep(1);
continue;
}
NetworkPacket *packet = (NetworkPacket *)(intptr_t)packet_ptr;
// 处理数据包(示例:简单的Echo服务)
printf("收到来自 %s:%d 的数据包,长度: %dn",
inet_ntoa(packet->client_addr.sin_addr),
ntohs(packet->client_addr.sin_port),
packet->length);
// 将处理后的数据包放入发送队列
thread_safe_enqueue(server->send_queue, (int)(intptr_t)packet);
}
return NULL;
}
// 发送线程函数
void* network_send_thread(void *arg) {
NetworkServer *server = (NetworkServer *)arg;
while (server->running) {
int packet_ptr;
if (thread_safe_dequeue(server->send_queue, &packet_ptr) != 0) {
sleep(1);
continue;
}
NetworkPacket *packet = (NetworkPacket *)(intptr_t)packet_ptr;
// 发送数据包
sendto(server->server_fd, packet->data, packet->length, 0,
(struct sockaddr *)&packet->client_addr, packet->addr_len);
free(packet);
}
return NULL;
}
// 初始化网络服务器
NetworkServer* init_network_server(int port) {
NetworkServer *server = (NetworkServer *)malloc(sizeof(NetworkServer));
if (server == NULL) {
return NULL;
}
// 创建UDP socket
server->server_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (server->server_fd < 0) {
free(server);
return NULL;
}
// 绑定端口
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port);
if (bind(server->server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
close(server->server_fd);
free(server);
return NULL;
}
// 初始化队列
server->receive_queue = init_thread_safe_queue(MAX_QUEUE_SIZE);
server->send_queue = init_thread_safe_queue(MAX_QUEUE_SIZE);
if (server->receive_queue == NULL || server->send_queue == NULL) {
destroy_thread_safe_queue(server->receive_queue);
destroy_thread_safe_queue(server->send_queue);
close(server->server_fd);
free(server);
return NULL;
}
server->running = true;
// 创建线程
pthread_create(&server->receive_thread, NULL, network_receive_thread, server);
pthread_create(&server->worker_thread, NULL, network_worker_thread, server);
pthread_create(&server->send_thread, NULL, network_send_thread, server);
return server;
}
// 停止网络服务器
void stop_network_server(NetworkServer *server) {
if (server == NULL) {
return;
}
server->running = false;
// 等待线程结束
pthread_join(server->receive_thread, NULL);
pthread_join(server->worker_thread, NULL);
pthread_join(server->send_thread, NULL);
// 清理资源
close(server->server_fd);
destroy_thread_safe_queue(server->receive_queue);
destroy_thread_safe_queue(server->send_queue);
free(server);
}
// 测试网络服务器
void test_network_server() {
int port = 8888;
NetworkServer *server = init_network_server(port);
if (server == NULL) {
printf("服务器初始化失败n");
return;
}
printf("UDP Echo服务器启动,监听端口 %dn", port);
printf("按任意键停止服务器...n");
getchar(); // 等待用户输入
printf("停止服务器...n");
stop_network_server(server);
}
7.3 内存管理中的应用
内存池管理器:
// 链表队列在内存管理中的应用
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stddef.h>
#define MEMORY_POOL_DEFAULT_SIZE 1024 * 1024 // 1MB
#define BLOCK_HEADER_SIZE sizeof(MemoryBlock)
// 内存块结构
typedef struct MemoryBlock {
size_t size; // 块大小
bool is_free; // 是否空闲
struct MemoryBlock *prev; // 前驱指针
struct MemoryBlock *next; // 后继指针
} MemoryBlock;
// 内存池管理器
typedef struct {
MemoryBlock *head; // 内存块链表头
MemoryBlock *tail; // 内存块链表尾
size_t total_size; // 总大小
size_t used_size; // 已使用大小
LinkedListQueue *free_blocks[8]; // 按大小分类的空闲块队列
} MemoryPoolManager;
// 初始化内存池
MemoryPoolManager* init_memory_pool(size_t size) {
if (size <= BLOCK_HEADER_SIZE) {
printf("内存池大小过小n");
return NULL;
}
MemoryPoolManager *manager = (MemoryPoolManager *)malloc(sizeof(MemoryPoolManager));
if (manager == NULL) {
printf("内存分配失败n");
return NULL;
}
// 分配内存池
char *memory = (char *)malloc(size);
if (memory == NULL) {
free(manager);
printf("内存分配失败n");
return NULL;
}
// 初始化内存块
MemoryBlock *block = (MemoryBlock *)memory;
block->size = size - BLOCK_HEADER_SIZE;
block->is_free = true;
block->prev = NULL;
block->next = NULL;
manager->head = block;
manager->tail = block;
manager->total_size = size;
manager->used_size = 0;
// 初始化空闲块队列
for (int i = 0; i < 8; i++) {
manager->free_blocks[i] = init_linked_list_queue(0);
}
// 将初始块添加到对应队列
int queue_index = get_queue_index(block->size);
enqueue(manager->free_blocks[queue_index], (int)(intptr_t)block);
return manager;
}
// 根据大小获取队列索引
int get_queue_index(size_t size) {
if (size <= 64) return 0;
if (size <= 128) return 1;
if (size <= 256) return 2;
if (size <= 512) return 3;
if (size <= 1024) return 4;
if (size <= 4096) return 5;
if (size <= 16384) return 6;
return 7; // 大于16KB
}
// 内存分配
void* pool_malloc(MemoryPoolManager *manager, size_t size) {
if (manager == NULL || size == 0) {
return NULL;
}
// 找到合适的队列
int queue_index = get_queue_index(size);
// 从对应队列查找
for (int i = queue_index; i < 8; i++) {
if (!is_queue_empty(manager->free_blocks[i])) {
int block_ptr;
dequeue(manager->free_blocks[i], &block_ptr);
MemoryBlock *block = (MemoryBlock *)(intptr_t)block_ptr;
block->is_free = false;
manager->used_size += block->size + BLOCK_HEADER_SIZE;
// 如果块过大,分割成小块
if (block->size > size + BLOCK_HEADER_SIZE + 64) { // 至少保留64字节
MemoryBlock *new_block = (MemoryBlock *)((char *)block + BLOCK_HEADER_SIZE + size);
new_block->size = block->size - size - BLOCK_HEADER_SIZE;
new_block->is_free = true;
new_block->prev = block;
new_block->next = block->next;
if (block->next != NULL) {
block->next->prev = new_block;
} else {
manager->tail = new_block;
}
block->next = new_block;
block->size = size;
// 将新块添加到对应队列
int new_queue_index = get_queue_index(new_block->size);
enqueue(manager->free_blocks[new_queue_index], (int)(intptr_t)new_block);
}
return (char *)block + BLOCK_HEADER_SIZE;
}
}
// 没有合适的块,尝试合并相邻的空闲块
if (merge_free_blocks(manager)) {
return pool_malloc(manager, size);
}
// 仍然没有合适的块,返回NULL
return NULL;
}
// 合并相邻的空闲块
bool merge_free_blocks(MemoryPoolManager *manager) {
if (manager == NULL) {
return false;
}
bool merged = false;
MemoryBlock *current = manager->head;
while (current != NULL && current->next != NULL) {
if (current->is_free && current->next->is_free) {
// 合并两个相邻的空闲块
current->size += current->next->size + BLOCK_HEADER_SIZE;
current->next = current->next->next;
if (current->next != NULL) {
current->next->prev = current;
} else {
manager->tail = current;
}
merged = true;
} else {
current = current->next;
}
}
return merged;
}
// 内存释放
void pool_free(MemoryPoolManager *manager, void *ptr) {
if (manager == NULL || ptr == NULL) {
return;
}
MemoryBlock *block = (MemoryBlock *)((char *)ptr - BLOCK_HEADER_SIZE);
block->is_free = true;
manager->used_size -= block->size + BLOCK_HEADER_SIZE;
// 将块添加到对应队列
int queue_index = get_queue_index(block->size);
enqueue(manager->free_blocks[queue_index], (int)(intptr_t)block);
// 尝试合并相邻的空闲块
merge_free_blocks(manager);
}
// 测试内存池
void test_memory_pool() {
const size_t pool_size = 4 * 1024 * 1024; // 4MB
MemoryPoolManager *manager = init_memory_pool(pool_size);
if (manager == NULL) {
return;
}
printf("内存池初始化成功,总大小: %zu MBn", pool_size / (1024 * 1024));
// 分配内存
void *ptr1 = pool_malloc(manager, 1024);
void *ptr2 = pool_malloc(manager, 2048);
void *ptr3 = pool_malloc(manager, 4096);
printf("分配内存后,使用率: %.2f%%n",
(double)manager->used_size / manager->total_size * 100);
// 释放内存
pool_free(manager, ptr2);
printf("释放部分内存后,使用率: %.2f%%n",
(double)manager->used_size / manager->total_size * 100);
// 再次分配
void *ptr4 = pool_malloc(manager, 1536);
printf("再次分配后,使用率: %.2f%%n",
(double)manager->used_size / manager->total_size * 100);
// 清理
pool_free(manager, ptr1);
pool_free(manager, ptr3);
pool_free(manager, ptr4);
printf("全部释放后,使用率: %.2f%%n",
(double)manager->used_size / manager->total_size * 100);
// 销毁内存池
destroy_memory_pool(manager);
}
8. 性能分析与优化策略
8.1 时间复杂度分析
各种链表队列的时间复杂度:
// 链表队列时间复杂度分析
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void analyze_time_complexity() {
printf("链表队列时间复杂度分析:n");
printf("+----------------+----------------+----------------+----------------+----------------+n");
printf("| 操作类型 | 单链表队列 | 双向链表队列| 循环链表队列| 优先级队列 |n");
printf("+----------------+----------------+----------------+----------------+----------------+n");
printf("| 入队操作 | O(1) | O(1) | O(1) | O(n) |n");
printf("| 出队操作 | O(1) | O(1) | O(1) | O(1) |n");
printf("| 获取队头 | O(1) | O(1) | O(1) | O(1) |n");
printf("| 获取队尾 | O(1) | O(1) | O(1) | O(n) |n");
printf("| 查找元素 | O(n) | O(n) | O(n) | O(n) |n");
printf("| 删除指定元素 | O(n) | O(n) | O(n) | O(n) |n");
printf("+----------------+----------------+----------------+----------------+----------------+n");
}
// 空间复杂度分析
void analyze_space_complexity() {
printf("n链表队列空间复杂度分析:n");
printf("+----------------+----------------+----------------+----------------+n");
printf("| 队列类型 | 空间复杂度 | 额外空间 | 特点 |n");
printf("+----------------+----------------+----------------+----------------+n");
printf("| 单链表队列 | O(n) | O(n) | 每个节点一个指针|n");
printf("| 双向链表队列 | O(n) | O(2n) | 每个节点两个指针|n");
printf("| 循环链表队列 | O(n) | O(n) | 尾指针指向头节点|n");
printf("| 优先级队列 | O(n) | O(n) | 按优先级排序 |n");
printf("+----------------+----------------+----------------+----------------+n");
}
8.2 性能测试与比较
性能测试框架:
// 链表队列性能测试
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#define TEST_SIZE 100000
#define TEST_ROUNDS 10
// 获取当前时间(毫秒)
long long get_current_time() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (long long)tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
// 生成随机数据
void generate_random_data(int *data, int size) {
for (int i = 0; i < size; i++) {
data[i] = rand();
}
}
// 测试单链表队列性能
void test_singly_queue_performance() {
int *data = (int *)malloc(TEST_SIZE * sizeof(int));
generate_random_data(data, TEST_SIZE);
long long total_time = 0;
for (int round = 0; round < TEST_ROUNDS; round++) {
LinkedListQueue *queue = init_linked_list_queue(0);
if (queue == NULL) {
continue;
}
long long start_time = get_current_time();
// 测试入队
for (int i = 0; i < TEST_SIZE; i++) {
enqueue(queue, data[i]);
}
// 测试出队
int temp;
for (int i = 0; i < TEST_SIZE; i++) {
dequeue(queue, &temp);
}
long long end_time = get_current_time();
total_time += (end_time - start_time);
destroy_queue(queue);
}
printf("单链表队列平均时间: %.2f msn", (double)total_time / TEST_ROUNDS);
free(data);
}
// 测试双向链表队列性能
void test_doubly_queue_performance() {
int *data = (int *)malloc(TEST_SIZE * sizeof(int));
generate_random_data(data, TEST_SIZE);
long long total_time = 0;
for (int round = 0; round < TEST_ROUNDS; round++) {
DoublyLinkedListQueue *queue = init_doubly_queue(0);
if (queue == NULL) {
continue;
}
long long start_time = get_current_time();
// 测试入队
for (int i = 0; i < TEST_SIZE; i++) {
doubly_enqueue_rear(queue, data[i]);
}
// 测试出队
int temp;
for (int i = 0; i < TEST_SIZE; i++) {
doubly_dequeue_front(queue, &temp);
}
long long end_time = get_current_time();
total_time += (end_time - start_time);
destroy_doubly_queue(queue);
}
printf("双向链表队列平均时间: %.2f msn", (double)total_time / TEST_ROUNDS);
free(data);
}
// 测试循环链表队列性能
void test_circular_queue_performance() {
int *data = (int *)malloc(TEST_SIZE * sizeof(int));
generate_random_data(data, TEST_SIZE);
long long total_time = 0;
for (int round = 0; round < TEST_ROUNDS; round++) {
CircularLinkedListQueue *queue = init_circular_queue(0);
if (queue == NULL) {
continue;
}
long long start_time = get_current_time();
// 测试入队
for (int i = 0; i < TEST_SIZE; i++) {
circular_enqueue(queue, data[i]);
}
// 测试出队
int temp;
for (int i = 0; i < TEST_SIZE; i++) {
circular_dequeue(queue, &temp);
}
long long end_time = get_current_time();
total_time += (end_time - start_time);
destroy_circular_queue(queue);
}
printf("循环链表队列平均时间: %.2f msn", (double)total_time / TEST_ROUNDS);
free(data);
}
// 测试优先级队列性能
void test_priority_queue_performance() {
int *data = (int *)malloc(TEST_SIZE * sizeof(int));
int *priorities = (int *)malloc(TEST_SIZE * sizeof(int));
generate_random_data(data, TEST_SIZE);
generate_random_data(priorities, TEST_SIZE);
long long total_time = 0;
for (int round = 0; round < TEST_ROUNDS; round++) {
PriorityLinkedListQueue *queue = init_priority_queue(0);
if (queue == NULL) {
continue;
}
long long start_time = get_current_time();
// 测试入队
for (int i = 0; i < TEST_SIZE; i++) {
priority_enqueue(queue, data[i], priorities[i] % 10);
}
// 测试出队
int temp_data, temp_priority;
for (int i = 0; i < TEST_SIZE; i++) {
priority_dequeue(queue, &temp_data, &temp_priority);
}
long long end_time = get_current_time();
total_time += (end_time - start_time);
destroy_priority_queue(queue);
}
printf("优先级链表队列平均时间: %.2f msn", (double)total_time / TEST_ROUNDS);
free(data);
free(priorities);
}
// 运行所有性能测试
void run_all_performance_tests() {
printf("开始链表队列性能测试...n");
printf("测试规模: %d 操作,%d 轮次nn", TEST_SIZE, TEST_ROUNDS);
test_singly_queue_performance();
test_doubly_queue_performance();
test_circular_queue_performance();
test_priority_queue_performance();
printf("n性能测试完成n");
}
8.3 优化策略
缓存优化:
// 链表队列缓存优化
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define CACHE_LINE_SIZE 64
// 缓存友好的链表节点
typedef struct CacheFriendlyNode {
int data;
struct CacheFriendlyNode *next;
char padding[CACHE_LINE_SIZE - sizeof(int) - sizeof(void*)];
} CacheFriendlyNode;
// 缓存友好的队列
typedef struct {
CacheFriendlyNode *front;
CacheFriendlyNode *rear;
int size;
int max_size;
} CacheFriendlyQueue;
// 初始化缓存友好队列
CacheFriendlyQueue* init_cache_friendly_queue(int max_size) {
CacheFriendlyQueue *queue = (CacheFriendlyQueue *)malloc(sizeof(CacheFriendlyQueue));
if (queue == NULL) {
return NULL;
}
queue->front = NULL;
queue->rear = NULL;
queue->size = 0;
queue->max_size = max_size;
return queue;
}
// 预分配节点数组
#define PREALLOCATE_SIZE 10000
// 预分配队列
typedef struct {
CacheFriendlyNode nodes[PREALLOCATE_SIZE];
int free_list[PREALLOCATE_SIZE];
int free_count;
CacheFriendlyNode *front;
CacheFriendlyNode *rear;
int size;
} PreallocatedQueue;
// 初始化预分配队列
PreallocatedQueue* init_preallocated_queue() {
PreallocatedQueue *queue = (PreallocatedQueue *)malloc(sizeof(PreallocatedQueue));
if (queue == NULL) {
return NULL;
}
queue->front = NULL;
queue->rear = NULL;
queue->size = 0;
queue->free_count = PREALLOCATE_SIZE;
// 初始化空闲列表
for (int i = 0; i < PREALLOCATE_SIZE; i++) {
queue->free_list[i] = i;
queue->nodes[i].next = NULL;
}
return queue;
}
// 从预分配队列获取节点
CacheFriendlyNode* prealloc_get_node(PreallocatedQueue *queue, int data) {
if (queue == NULL || queue->free_count == 0) {
return NULL;
}
int index = queue->free_list[--queue->free_count];
queue->nodes[index].data = data;
queue->nodes[index].next = NULL;
return &queue->nodes[index];
}
// 回收节点到预分配队列
void prealloc_release_node(PreallocatedQueue *queue, CacheFriendlyNode *node) {
if (queue == NULL || node == NULL || queue->free_count >= PREALLOCATE_SIZE) {
return;
}
// 计算节点索引
ptrdiff_t offset = node - queue->nodes;
if (offset < 0 || offset >= PREALLOCATE_SIZE) {
return;
}
queue->free_list[queue->free_count++] = (int)offset;
}
// 预分配队列的入队操作
int prealloc_enqueue(PreallocatedQueue *queue, int data) {
if (queue == NULL) {
return -1;
}
CacheFriendlyNode *new_node = prealloc_get_node(queue, data);
if (new_node == NULL) {
return -1;
}
if (queue->rear == NULL) {
queue->front = new_node;
queue->rear = new_node;
} else {
queue->rear->next = new_node;
queue->rear = new_node;
}
queue->size++;
return 0;
}
// 预分配队列的出队操作
int prealloc_dequeue(PreallocatedQueue *queue, int *data) {
if (queue == NULL || data == NULL || queue->size == 0) {
return -1;
}
CacheFriendlyNode *temp = queue->front;
*data = temp->data;
queue->front = queue->front->next;
if (queue->front == NULL) {
queue->rear = NULL;
}
prealloc_release_node(queue, temp);
queue->size--;
return 0;
}
9. 常见问题与解决方案
9.1 内存泄漏问题
内存泄漏检测与解决:
// 链表队列内存泄漏检测与解决
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
// 内存跟踪结构
typedef struct {
void **allocated_blocks;
int count;
int capacity;
} MemoryTracker;
// 初始化内存跟踪器
MemoryTracker* init_memory_tracker(int capacity) {
MemoryTracker *tracker = (MemoryTracker *)malloc(sizeof(MemoryTracker));
if (tracker == NULL) {
return NULL;
}
tracker->allocated_blocks = (void **)malloc(capacity * sizeof(void *));
if (tracker->allocated_blocks == NULL) {
free(tracker);
return NULL;
}
tracker->count = 0;
tracker->capacity = capacity;
return tracker;
}
// 跟踪内存分配
void* tracked_malloc(MemoryTracker *tracker, size_t size, const char *file, int line) {
void *ptr = malloc(size);
if (ptr != NULL && tracker != NULL && tracker->count < tracker->capacity) {
tracker->allocated_blocks[tracker->count++] = ptr;
}
return ptr;
}
// 跟踪内存释放
void tracked_free(MemoryTracker *tracker, void *ptr) {
if (ptr == NULL || tracker == NULL) {
free(ptr);
return;
}
// 从跟踪列表中移除
for (int i = 0; i < tracker->count; i++) {
if (tracker->allocated_blocks[i] == ptr) {
tracker->allocated_blocks[i] = tracker->allocated_blocks[tracker->count - 1];
tracker->count--;
break;
}
}
free(ptr);
}
// 检查内存泄漏
void check_memory_leaks(MemoryTracker *tracker) {
if (tracker == NULL) {
return;
}
if (tracker->count > 0) {
printf("检测到%d处内存泄漏:n", tracker->count);
for (int i = 0; i < tracker->count; i++) {
printf(" 未释放的内存块: %pn", tracker->allocated_blocks[i]);
}
} else {
printf("未检测到内存泄漏n");
}
}
// 智能指针队列
typedef struct SmartQueueNode {
int data;
struct SmartQueueNode *next;
int ref_count;
} SmartQueueNode;
typedef struct {
SmartQueueNode *front;
SmartQueueNode *rear;
int size;
MemoryTracker *tracker;
} SmartQueue;
// 创建智能节点
SmartQueueNode* create_smart_node(SmartQueue *queue, int data) {
SmartQueueNode *node = (SmartQueueNode *)tracked_malloc(queue->tracker, sizeof(SmartQueueNode), __FILE__, __LINE__);
if (node == NULL) {
return NULL;
}
node->data = data;
node->next = NULL;
node->ref_count = 1;
return node;
}
// 智能指针引用
void smart_node_retain(SmartQueueNode *node) {
if (node != NULL) {
node->ref_count++;
}
}
// 智能指针释放
void smart_node_release(SmartQueueNode *node, MemoryTracker *tracker) {
if (node == NULL) {
return;
}
node->ref_count--;
if (node->ref_count <= 0) {
tracked_free(tracker, node);
}
}
// 初始化智能队列
SmartQueue* init_smart_queue() {
SmartQueue *queue = (SmartQueue *)malloc(sizeof(SmartQueue));
if (queue == NULL) {
return NULL;
}
queue->front = NULL;
queue->rear = NULL;
queue->size = 0;
queue->tracker = init_memory_tracker(10000);
return queue;
}
// 智能队列入队
int smart_enqueue(SmartQueue *queue, int data) {
if (queue == NULL) {
return -1;
}
SmartQueueNode *new_node = create_smart_node(queue, data);
if (new_node == NULL) {
return -1;
}
if (queue->rear == NULL) {
queue->front = new_node;
queue->rear = new_node;
} else {
queue->rear->next = new_node;
queue->rear = new_node;
}
queue->size++;
return 0;
}
// 智能队列出队
int smart_dequeue(SmartQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
return -1;
}
if (queue->size == 0) {
return -1;
}
SmartQueueNode *temp = queue->front;
*data = temp->data;
queue->front = queue->front->next;
if (queue->front == NULL) {
queue->rear = NULL;
}
smart_node_release(temp, queue->tracker);
queue->size--;
return 0;
}
// 销毁智能队列
void destroy_smart_queue(SmartQueue *queue) {
if (queue == NULL) {
return;
}
SmartQueueNode *current = queue->front;
while (current != NULL) {
SmartQueueNode *temp = current;
current = current->next;
smart_node_release(temp, queue->tracker);
}
check_memory_leaks(queue->tracker);
free(queue->tracker->allocated_blocks);
free(queue->tracker);
free(queue);
}
9.2 线程安全问题
线程安全解决方案:
// 链表队列线程安全问题解决方案
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdbool.h>
#include <errno.h>
// 无锁队列实现
typedef struct LockFreeNode {
int data;
struct LockFreeNode *next;
atomic_flag lock;
} LockFreeNode;
typedef struct {
LockFreeNode *head;
LockFreeNode *tail;
atomic_int size;
atomic_bool stopped;
} LockFreeQueue;
// 初始化无锁节点
LockFreeNode* create_lock_free_node(int data) {
LockFreeNode *node = (LockFreeNode *)malloc(sizeof(LockFreeNode));
if (node == NULL) {
return NULL;
}
node->data = data;
node->next = NULL;
atomic_flag_clear(&node->lock);
return node;
}
// 初始化无锁队列
LockFreeQueue* init_lock_free_queue() {
LockFreeQueue *queue = (LockFreeQueue *)malloc(sizeof(LockFreeQueue));
if (queue == NULL) {
return NULL;
}
// 创建哨兵节点
LockFreeNode *sentinel = create_lock_free_node(0);
if (sentinel == NULL) {
free(queue);
return NULL;
}
queue->head = sentinel;
queue->tail = sentinel;
atomic_init(&queue->size, 0);
atomic_init(&queue->stopped, false);
return queue;
}
// 无锁入队操作
int lock_free_enqueue(LockFreeQueue *queue, int data) {
if (queue == NULL) {
return -1;
}
if (atomic_load(&queue->stopped)) {
return -1;
}
LockFreeNode *new_node = create_lock_free_node(data);
if (new_node == NULL) {
return -1;
}
// 自旋直到获取尾节点锁
while (atomic_flag_test_and_set(&queue->tail->lock)) {
// 等待
}
// 将新节点链接到尾部
queue->tail->next = new_node;
queue->tail = new_node;
atomic_fetch_add(&queue->size, 1);
// 释放尾节点锁
atomic_flag_clear(&queue->tail->lock);
return 0;
}
// 无锁出队操作
int lock_free_dequeue(LockFreeQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
return -1;
}
if (atomic_load(&queue->stopped) && atomic_load(&queue->size) == 0) {
return -1;
}
// 自旋直到获取头节点锁
while (atomic_flag_test_and_set(&queue->head->lock)) {
// 等待
}
LockFreeNode *first = queue->head->next;
if (first == NULL) {
// 队列为空
atomic_flag_clear(&queue->head->lock);
return -1;
}
*data = first->data;
// 自旋直到获取第一个节点锁
while (atomic_flag_test_and_set(&first->lock)) {
// 等待
}
// 更新头节点
queue->head = first;
atomic_fetch_sub(&queue->size, 1);
// 释放锁
atomic_flag_clear(&first->lock);
atomic_flag_clear(&queue->head->lock);
return 0;
}
// 测试无锁队列的多线程性能
#define NUM_THREADS 4
#define TASK_PER_THREAD 100000
LockFreeQueue *test_queue;
atomic_long total_enqueued;
atomic_long total_dequeued;
void* producer_thread(void *arg) {
int thread_id = *(int *)arg;
for (int i = 0; i < TASK_PER_THREAD; i++) {
int data = thread_id * TASK_PER_THREAD + i;
while (lock_free_enqueue(test_queue, data) != 0) {
// 重试
}
atomic_fetch_add(&total_enqueued, 1);
}
return NULL;
}
void* consumer_thread(void *arg) {
int data;
while (atomic_load(&total_dequeued) < NUM_THREADS * TASK_PER_THREAD) {
if (lock_free_dequeue(test_queue, &data) == 0) {
atomic_fetch_add(&total_dequeued, 1);
}
}
return NULL;
}
void test_lock_free_queue() {
test_queue = init_lock_free_queue();
if (test_queue == NULL) {
return;
}
atomic_init(&total_enqueued, 0);
atomic_init(&total_dequeued, 0);
pthread_t producer_threads[NUM_THREADS];
pthread_t consumer_threads[NUM_THREADS];
int thread_ids[NUM_THREADS];
// 创建生产者线程
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i;
pthread_create(&producer_threads[i], NULL, producer_thread, &thread_ids[i]);
}
// 创建消费者线程
for (int i = 0; i < NUM_THREADS; i++) {
pthread_create(&consumer_threads[i], NULL, consumer_thread, NULL);
}
// 等待所有线程完成
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(producer_threads[i], NULL);
}
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(consumer_threads[i], NULL);
}
printf("无锁队列测试结果:n");
printf("入队总数: %lldn", atomic_load(&total_enqueued));
printf("出队总数: %lldn", atomic_load(&total_dequeued));
printf("队列剩余: %dn", atomic_load(&test_queue->size));
// 清理资源
atomic_store(&test_queue->stopped, true);
destroy_lock_free_queue(test_queue);
}
9.3 错误处理与调试
错误处理框架:
// 链表队列错误处理与调试框架
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
// 错误码定义
typedef enum {
QUEUE_SUCCESS = 0,
QUEUE_ERROR_NULL_POINTER,
QUEUE_ERROR_OUT_OF_MEMORY,
QUEUE_ERROR_QUEUE_FULL,
QUEUE_ERROR_QUEUE_EMPTY,
QUEUE_ERROR_INVALID_PARAMETER,
QUEUE_ERROR_INDEX_OUT_OF_RANGE,
QUEUE_ERROR_THREAD_FAILED,
QUEUE_ERROR_LOCK_FAILED,
QUEUE_ERROR_UNKNOWN
} QueueError;
// 错误信息映射
const char* queue_error_messages[] = {
"操作成功",
"空指针错误",
"内存不足",
"队列已满",
"队列为空",
"参数无效",
"索引超出范围",
"线程创建失败",
"锁操作失败",
"未知错误"
};
// 获取错误信息
const char* queue_get_error_message(QueueError error) {
if (error >= 0 && error < sizeof(queue_error_messages) / sizeof(queue_error_messages[0])) {
return queue_error_messages[error];
}
return "未知错误码";
}
// 调试配置
typedef struct {
bool enable_debug;
bool enable_memory_tracking;
bool enable_performance_profiling;
FILE *log_file;
} QueueDebugConfig;
// 全局调试配置
QueueDebugConfig queue_debug_config = {
.enable_debug = false,
.enable_memory_tracking = false,
.enable_performance_profiling = false,
.log_file = NULL
};
// 调试日志函数
void queue_debug_log(const char *format, ...) {
if (!queue_debug_config.enable_debug) {
return;
}
va_list args;
va_start(args, format);
if (queue_debug_config.log_file != NULL) {
vfprintf(queue_debug_config.log_file, format, args);
fprintf(queue_debug_config.log_file, "n");
fflush(queue_debug_config.log_file);
} else {
vprintf(format, args);
printf("n");
}
va_end(args);
}
// 性能分析结构
typedef struct {
long long enqueue_count;
long long dequeue_count;
long long enqueue_time;
long long dequeue_time;
long long total_operations;
long long total_time;
} QueuePerformanceStats;
// 带错误处理和调试的队列
typedef struct {
LinkedListQueue *base_queue;
QueuePerformanceStats stats;
QueueDebugConfig debug_config;
} DebugLinkedListQueue;
// 初始化调试队列
QueueError debug_queue_init(DebugLinkedListQueue **queue, int max_size, QueueDebugConfig config) {
if (queue == NULL) {
return QUEUE_ERROR_NULL_POINTER;
}
*queue = (DebugLinkedListQueue *)malloc(sizeof(DebugLinkedListQueue));
if (*queue == NULL) {
return QUEUE_ERROR_OUT_OF_MEMORY;
}
(*queue)->base_queue = init_linked_list_queue(max_size);
if ((*queue)->base_queue == NULL) {
free(*queue);
*queue = NULL;
return QUEUE_ERROR_OUT_OF_MEMORY;
}
// 初始化性能统计
memset(&(*queue)->stats, 0, sizeof(QueuePerformanceStats));
(*queue)->debug_config = config;
queue_debug_log("调试队列初始化成功,最大容量: %d", max_size);
return QUEUE_SUCCESS;
}
// 调试队列入队
QueueError debug_queue_enqueue(DebugLinkedListQueue *queue, int data) {
if (queue == NULL) {
return QUEUE_ERROR_NULL_POINTER;
}
long long start_time = get_current_time();
int result = enqueue(queue->base_queue, data);
long long end_time = get_current_time();
long long elapsed = end_time - start_time;
// 更新性能统计
queue->stats.enqueue_count++;
queue->stats.enqueue_time += elapsed;
queue->stats.total_operations++;
queue->stats.total_time += elapsed;
if (result == 0) {
queue_debug_log("入队成功: %d, 队列大小: %d", data, queue->base_queue->size);
return QUEUE_SUCCESS;
} else if (is_queue_full(queue->base_queue)) {
queue_debug_log("入队失败: 队列已满,数据: %d", data);
return QUEUE_ERROR_QUEUE_FULL;
} else {
queue_debug_log("入队失败: 未知错误,数据: %d", data);
return QUEUE_ERROR_UNKNOWN;
}
}
// 调试队列出队
QueueError debug_queue_dequeue(DebugLinkedListQueue *queue, int *data) {
if (queue == NULL || data == NULL) {
return QUEUE_ERROR_NULL_POINTER;
}
long long start_time = get_current_time();
int result = dequeue(queue->base_queue, data);
long long end_time = get_current_time();
long long elapsed = end_time - start_time;
// 更新性能统计
queue->stats.dequeue_count++;
queue->stats.dequeue_time += elapsed;
queue->stats.total_operations++;
queue->stats.total_time += elapsed;
if (result == 0) {
queue_debug_log("出队成功: %d, 队列大小: %d", *data, queue->base_queue->size);
return QUEUE_SUCCESS;
} else {
queue_debug_log("出队失败: 队列为空");
return QUEUE_ERROR_QUEUE_EMPTY;
}
}
// 获取性能统计信息
void debug_queue_get_stats(DebugLinkedListQueue *queue, QueuePerformanceStats *stats) {
if (queue == NULL || stats == NULL) {
return;
}
*stats = queue->stats;
}
// 打印性能报告
void debug_queue_print_performance_report(DebugLinkedListQueue *queue) {
if (queue == NULL || !queue->debug_config.enable_performance_profiling) {
return;
}
QueuePerformanceStats stats = queue->stats;
printf("n=== 链表队列性能报告 ===n");
printf("总操作数: %lldn", stats.total_operations);
printf("总耗时: %lld msn", stats.total_time);
printf("平均操作时间: %.2f msn", (double)stats.total_time / stats.total_operations);
if (stats.enqueue_count > 0) {
printf("入队操作: %lld 次, 总耗时: %lld ms, 平均: %.2f msn",
stats.enqueue_count, stats.enqueue_time,
(double)stats.enqueue_time / stats.enqueue_count);
}
if (stats.dequeue_count > 0) {
printf("出队操作: %lld 次, 总耗时: %lld ms, 平均: %.2f msn",
stats.dequeue_count, stats.dequeue_time,
(double)stats.dequeue_time / stats.dequeue_count);
}
printf("======================n");
}