C语言 使用链表实现队列接口

前言

1. 队列是一种常见的数据结合,具有先入先出的特点。数据从队列的头部(front)剥离,从队列的尾部(rear)插入。使用队列可以作为数据缓冲,也可以用作异步通讯。博主在实现OCPP 1.6J协议时,需要对websokcet收到的消息进行异步通信,即将需要发送的数据写进队列中,按顺序发出。内容为字符串类型(当然可以根据实际需求修改结构体中的定义来完成应用场景)。

2. 代码分为 queue.c和queue.h,可以很容易的集成到你的项目中

正文

queue.c

#include 
#include 
#include 
#include "queue.h"

void init_queue(queue_t queue) { 
	if (NULL == queue) {
		return;
    }
    
    queue->front = NULL;
    queue->rear = NULL;
}

bool is_empty(queue_t queue) {
	return (queue->front == NULL);  //当头指针为NULL时队列没有数据
}

queue_node_t *node_malloc() {
	 queue_node_t *p = (queue_node_t *)malloc(sizeof(queue_node_t));
	 memset(p->buff, 0, sizeof(p->buff));
	 p->next = NULL;

	 return p;
}

int Enqueue(queue_t queue, char *buff) {
   	queue_node_t *node = node_malloc();

	if (strlen(buff) > 4096) {
		return -1;
	}

	strcpy(node->buff, buff);
	
	if (queue->rear == NULL) {       //第一次入队时头尾指针都指向第一个节点
		queue->rear = node;
		queue->front = node;
	} else {						 //非第一次入队,链表尾加上新节点,尾指针指向它
		queue->rear->next = node;
		queue->rear = node;	
		node->next = NULL;
	}

	return 0;
}

int Dequeue(queue_t queue, char *buff) {
    if (is_empty(queue)) {    //检查队列为空的话返回错误
        return -1;
    }

	queue_node_t *p = queue->front;

	strcpy(buff, p->buff);
    queue->front = queue->front->next;
	free(p);

	if (queue->front == NULL) {  //出队后队列为空,初始化队列尾指针,避免头指针越过尾指针
		queue->rear = NULL;
	}
	
    return 0;

}

void Destroy_queue(queue_t queue) {
    queue_node_t *p_cur = queue->front;
    queue_node_t *p;

    while (NULL != p_cur ) {   //释放所有节点空间,销毁队列,防止内存泄漏
    	p = p_cur ->next;
        free(p_cur );
        p_cur = p;
    }

}

queue.h

#ifndef _queue_h 
#define _queue_h 

#include 

#define MAX_BUFF_SIZE 4096

struct queue_node_s {					//定义队列中的节点的结构体
    char buff[MAX_BUFF_SIZE];
	struct queue_node_s *next;  
};

typedef struct queue_node_s queue_node_t;

struct queue_s {                       //定义队列结构体
	queue_node_t *front;
	queue_node_t *rear;
};

typedef struct queue_s* queue_t;

void init_queue(queue_t queue);             	//初始化队列

int Enqueue(queue_t queue, char *buff);      //入队,从队尾(rear)入

int Dequeue(queue_t queue, char *buff);  	//出队,从队首(front)出

bool is_empty(queue_t queue);          		//队列为空则返回true

void Destroy_queue(queue_t queue);			//销毁队列,释放节点空间

#endif

快速使用

main.c

#include 
#include 
#include 
int main() {
	char buff[4096] = {0};
	struct queue_s queue;
	
	init_queue(&queue);

	Enqueue(&queue, "111");
	Enqueue(&queue, "222");
	Enqueue(&queue, "333");

	while (1) {
		int ret = Dequeue( &queue, buff);
		log_info("queue: %s", buff);
		memset(buff, 0, 4096);
		if (ret < 0) {
			log_info("queue is empty");
			break;
		}
	}

	Enqueue(&queue, "666");
	Dequeue( &queue, buff);
	log_info("queue: %s", buff);

	Destroy_queue(&queue);
}

PS: 其中log_info函数替换成你的输出函数,或者参考下面这篇文章实现日志接口。

linux C语言实现日志接口

输出结果 输出结果会是这样

C语言 使用链表实现队列接口_第1张图片

你可能感兴趣的:(链表,c语言,数据结构)