前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言实现链表队列LinkQueue

C语言实现链表队列LinkQueue

作者头像
小锋学长生活大爆炸
发布2020-10-28 11:34:05
7720
发布2020-10-28 11:34:05
举报

以下队列为自己设计,若有错误,欢迎大家指出,谢谢~~

本队列原理

- Node:节点

- xLinkQueue:节点控制器

-- head:总是指向队列头

-- end:总是指向队列尾

- 创建队列时,实际是创建了xLinkQueue,之后对队列的操作都是通过它

- 添加节点时,创建的Node,并将内容复制进它的buff中

- 弹出队列时,将Node中的内容先复制出来,在free释放内存

- 不是循环队列,有待改进

- 单个节点的buff最大不超过(1024*3),如queueCreate(20, 1024*3);(不知道为什么,在我的STM32F4上申请1024*4失败)

util.c

代码语言:javascript
复制
/**
	工具包
*/
#include "util.h"

static uint8_t stateBuf[][12] = {"OK", "OVERSIZE", "OVERLENGTH", "EMPTY", "None", "Malloc"};
enum QUEUE_STATE {
	QUEUE_OK = 0,
	QUEUE_OVERSIZE,
	QUEUE_OVERLENGTH, // 超过最大使用节点数
	QUEUE_EMPTY,  // 队列为空
	QUEUE_NONE,	// 没有队列
	QUEUE_MALLOC
};

static uint8_t levelBuf[][10] = {"Error", "Warn", "Info"};
enum QUEUE_DEBUG {
	QUEUE_ERROR = 0,
	QUEUE_WARN,
	QUEUE_INFO,
};

#define DEBUG 1
void queueDebug(enum QUEUE_DEBUG level, enum QUEUE_STATE state, char* ext)
{
#if DEBUG
	printf("queue[%s]: %s - %s\r\n", levelBuf[level], stateBuf[state], ext);
#endif
}

void queueInfo(xLinkQueue* queue)
{
	printf("************************\r\n");
	printf("max:%d\r\n", queue->max);
	printf("size:%d\r\n", queue->size);
	printf("length:%d\r\n", queue->length);
	printf("************************\r\n");
}

/** 
	遍历输出队列的buff
*/
void queueTraversal(xLinkQueue* queue)
{
	Node* q = queue->head;
	printf("********START********\r\n");
	for(uint8_t i=0; i<queue->length; i++) {
		printf("第%d/%d个:%s\r\n", i+1, queue->length, q->buff);
		q = q->next;
	}
	printf("*********END*********\r\n");
}

/**
	创建一个队列,返回队列控制句柄,max个节点,每个节点size字节大小
*/
xLinkQueue* queueCreate(uint16_t max, uint16_t size)
{
	xLinkQueue* xqueue = (xLinkQueue*)malloc(sizeof(xLinkQueue));
//	// 创建首节点
//	Node* p =(Node*)malloc(sizeof(Node));
//	p->buff =(uint8_t*)malloc(sizeof(uint8_t)*size);
//	memset(p->buff, 0, sizeof(uint8_t)*size);
//	p->next = NULL;
//	// 队列首尾都指向头结点
//	xqueue->head = p;
//	xqueue->end = p;
	xqueue->length = 0;
	xqueue->size = size;
	xqueue->max = max;
	
//	Node* temp = p;
//	// 创建剩余size-1个节点
//	for(uint8_t i=1; i<size; i++) {
//		Node* p =(Node*)malloc(sizeof(Node));
//		p->buff =(uint8_t*)malloc(sizeof(uint8_t)*size);
//		memset(p->buff, 0, sizeof(uint8_t)*size);
//		p->next = NULL;
//		temp->next = p;
//		temp = temp->next;
//	}
	return xqueue;
}

/** 
	添加一个节点到队列
*/
uint8_t queueAdd(xLinkQueue* queue, uint8_t* src, uint16_t len)
{
	if(queue == NULL) {
		queueDebug(QUEUE_ERROR, QUEUE_NONE, "队列不存在");
		return 0;
	}
	if(queue->length < queue->max) {
		// 创建新节点
		Node* newnode =(Node*)malloc(sizeof(Node));
		if(newnode == NULL){
			queueDebug(QUEUE_ERROR, QUEUE_MALLOC, "创建节点内存分配失败");
			return 0;
		}
		// 申请内存
		newnode->buff =(uint8_t*)malloc(sizeof(uint8_t)*(queue->size));
		if(newnode->buff == NULL){
			queueDebug(QUEUE_ERROR, QUEUE_MALLOC, "节点内存申请失败");
			return 0;
		}
		memset(newnode->buff, 0, sizeof(uint8_t)*(queue->size));
		// 数据填入新节点
		if(len > queue->size) {
			queueDebug(QUEUE_WARN, QUEUE_OVERSIZE, "大小超出,注意会有裁剪");
		}
		memcpy(newnode->buff, src, MIN(queue->size, len));
		newnode->buff[len] = '\0';
		// 新节点没有下一个节点
		newnode->next = NULL;
		// 获得尾节点
		Node* endnode = queue->end;
		// 连接 尾节点 -> 新节点
		endnode->next = newnode;
		// 更新尾节点
		queue->end = newnode;
		
		// 创建的是首节点
		if(queue->length == 0) {
			// 队列首尾都指向头结点
			queue->head = newnode;
			queue->end = newnode;
		}
		// 节点数+1
		queue->length ++;
		return 1;
	}else {
		queueDebug(QUEUE_ERROR, QUEUE_OVERLENGTH, "已达最大节点数");
		return 0;
	}
}

uint8_t queueEmpty(xLinkQueue* queue)
{
	return queue->length==0? QTRUE: QFALSE;
}


/**
	弹出队尾一个节点buff
*/
uint8_t queuePop(xLinkQueue* queue, uint8_t* buff)
{
	if(queue == NULL) {
		queueDebug(QUEUE_ERROR, QUEUE_NONE, "队列不存在");
		return 0;
	}
	Node* q = queue->head;
	if(queue->length > 0) {
		if(buff != NULL) {
			// 数据复制
			memcpy(buff, q->buff, strlen((const char*)q->buff));
		}
		// 释放内存
		free(q->buff);
		q->buff = NULL;
		free(q);
		q = NULL;
		// 更新首节点
		queue->head = queue->head->next;
		// 节点数-1
		queue->length --;
		return 1;
	} else {
		queueDebug(QUEUE_ERROR, QUEUE_EMPTY, "队列为空");
		return 0;
	}
}

/**
	从内存中销毁整个队列
*/
void queueDestory(xLinkQueue* queue)
{
	uint16_t total = queue->length;
	for(uint8_t i=0; i<total; i++) {
		queuePop(queue, NULL);
	}
	free(queue);
	queue = NULL;
}




void queueTest() 
{
	// 创建一个有10个节点,每个节点10字节的队列
	xLinkQueue* queue = queueCreate(10, 10);
	uint8_t buff[10] = {0};
	queuePop(queue, buff); 		// queue[Error]: EMPTY
	
	queueAdd(queue, (uint8_t*)"01", 3);
	queueAdd(queue, (uint8_t*)"23", 3);
	queueAdd(queue, (uint8_t*)"45", 3);
	queueAdd(queue, (uint8_t*)"67", 3);
	queueAdd(queue, (uint8_t*)"89", 3);
	queueAdd(queue, (uint8_t*)"asdfghjklqw", 12); // queue[Warn]: OVERSIZE
	queueTraversal(queue);
	
	queuePop(queue, buff);
	printf("pop: %s\r\n", buff);
	queueTraversal(queue);
	
	queueAdd(queue, (uint8_t*)"aa", 3);
	queueAdd(queue, (uint8_t*)"bb", 3);
	queueAdd(queue, (uint8_t*)"cc", 3);
	queueTraversal(queue);
	
//	for(uint8_t i=0; i<10; i++) { // queue[Error]: EMPTY
//		queuePop(q, NULL);
//	}
//	queueTraversal(q);
	

	queueDestory(queue);
	if(queuePop(queue, buff))
	printf("pop: %s\r\n", buff);
	printf("\r\ndemo end\r\n");
}

util.h

代码语言:javascript
复制
#ifndef __UTIL_H_
#define __UTIL_H_
#include "stm32f4xx.h"

#define MAX(x, y) (((x)>(y))? (x):(y))
#define MIN(x, y) (((x)<(y))? (x):(y))
#define QTRUE 1
#define QFALSE 0

typedef struct Node{
	uint8_t *buff;	
	struct Node *next;  // 下一个节点
}Node;


typedef struct xLinkQueue{
	Node *end;   		// 队列尾节点
	Node *head;  		// 队列头节点
	uint8_t length; // 记录队列的长度(已使用多少个节点)
	uint8_t size;		// 每个节点的buff的大小
	uint16_t max;    // 队列最大节点数(最多使用多少个节点)
}xLinkQueue;


void queueTraversal(xLinkQueue* queue);
xLinkQueue* queueCreate(uint16_t max, uint8_t size);
uint8_t queueAdd(xLinkQueue* queue, uint8_t* src, uint16_t len);
uint8_t queuePop(xLinkQueue* queue, uint8_t* buff);
void queueDestory(xLinkQueue* queue);
uint8_t queueEmpty(xLinkQueue* queue);
void queueInfo(xLinkQueue* queue);

void queueTest(void);


#endif

测试

代码语言:javascript
复制
queue[Error]: EMPTY
queue[Warn]: OVERSIZE
********START********
第1/6个:01
第2/6个:23
第3/6个:45
第4/6个:67
第5/6个:89
第6/6个:asdfghjklq
*********END*********
pop: 01
********START********
第1/5个:23
第2/5个:45
第3/5个:67
第4/5个:89
第5/5个:asdfghjklq
*********END*********
********START********
第1/8个:23
第2/8个:45
第3/8个:67
第4/8个:89
第5/8个:asdfghjklq
第6/8个:aa
第7/8个:bb
第8/8个:cc
*********END*********
queue[Error]: EMPTY

demo end
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-10-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 本队列原理
  • util.c
  • util.h
  • 测试
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档