motor_f407/User/system/lib/src/clist.c

339 lines
8.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file clist.c
* @author xxx
* @date 2023-08-08 23:18:09
* @brief
* @copyright Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#include "clist.h"
/**
* @brief 初始化链表
* @param {clist_node_t} **ppFirst 指向链表头节点的指针
* @return void
* @note 初始化链表,将链表头节点设置为空
*/
void clist_init(clist_node_t **ppFirst)
{
DBG_ASSERT(ppFirst != NULL __DBG_LINE);
*ppFirst = NULL;
}
/**
* @brief 打印链表
* @param {clist_node_t} First 链表头节点
* @return void
* @note 打印链表中的所有节点数据
*/
void clist_print(clist_node_t *First)
{
LOG_PRINT("list: ");
for (clist_node_t *p = First; p != NULL; p = p->Next)
LOG_PRINT("%d-->", p->data);
LOG_PRINT("\n");
}
/**
* @brief 获取链表节点数
* @param {clist_node_t} First 链表头节点
* @return {uint32_t} 链表节点数
* @note 遍历链表,计算节点数
*/
uint32_t clist_node_count(clist_node_t *First)
{
int32_t count = 0;
for (clist_node_t *p = First; p != NULL; p = p->Next)
count++;
return count;
}
/**
* @brief 申请新节点
* @param {cnode} data 节点数据
* @return {clist_node_t *} 新节点指针
* @note 分配内存,创建新节点
*/
static clist_node_t *CreateNode(cnode data)
{
clist_node_t *node = (clist_node_t *)osel_mem_alloc(sizeof(clist_node_t));
node->data = data;
node->Next = NULL;
return node;
}
/**
* @brief 尾部插入
* @param {clist_node_t} **ppFirst 指向链表头节点的指针
* @param {cnode} data 要插入的节点数据
* @return void
* @note 在链表末尾插入一个新节点新节点数据为data
*/
void clist_push_back(clist_node_t **ppFirst, cnode data)
{
DBG_ASSERT(ppFirst != NULL __DBG_LINE);
clist_node_t *node = CreateNode(data);
if (*ppFirst == NULL) // 判断链表不为空
{
*ppFirst = node;
return;
}
// 找链表中的最后一个节点
clist_node_t *p = *ppFirst;
while (p->Next != NULL)
p = p->Next;
p->Next = node; // 插入新申请的节点
}
/**
* @brief 头部插入
* @param {clist_node_t} **ppFirst 指向链表头节点的指针
* @param {cnode} data 要插入的节点数据
* @return void
* @note 在链表头部插入一个新节点新节点数据为data
*/
void clist_push_front(clist_node_t **ppFirst, cnode data)
{
DBG_ASSERT(ppFirst != NULL __DBG_LINE);
clist_node_t *node = CreateNode(data);
node->Next = *ppFirst;
*ppFirst = node;
}
/**
* @brief 尾部删除
* @param {clist_node_t} **ppFirst 指向链表头节点的指针
* @return void
* @note 删除链表中最后一个节点
*/
void clist_pop_back(clist_node_t **ppFirst) // 尾部删除
{
DBG_ASSERT(ppFirst != NULL __DBG_LINE);
DBG_ASSERT(*ppFirst != NULL __DBG_LINE);
if ((*ppFirst)->Next == NULL)
{
osel_mem_free(*ppFirst);
*ppFirst = NULL;
return;
}
clist_node_t *p = *ppFirst;
while (p->Next->Next != NULL)
p = p->Next;
osel_mem_free(p->Next);
p->Next = NULL;
}
/**
* @brief 头部删除
* @param {clist_node_t} **ppFirst 指向链表头节点的指针
* @return void
* @note 删除链表中第一个节点
*/
void clist_pop_front(clist_node_t **ppFirst)
{
DBG_ASSERT(ppFirst != NULL __DBG_LINE);
DBG_ASSERT(*ppFirst != NULL __DBG_LINE); // 链表不是空链表
clist_node_t *first = *ppFirst;
*ppFirst = (*ppFirst)->Next;
osel_mem_free(first);
}
/**
* @brief 按节点指针插入
* @param {clist_node_t} **ppFirst 指向链表头节点的指针
* @param {clist_node_t} *pPos 要插入的节点位置
* @param {cnode} data 要插入的节点数据
* @return void
* @note 在指定节点位置插入一个新节点新节点数据为data
*/
void clist_insert_for_node(clist_node_t **ppFirst, clist_node_t *pPos, cnode data)
{
DBG_ASSERT(ppFirst != NULL __DBG_LINE);
if (*ppFirst == pPos)
{
clist_push_front(ppFirst, data);
return;
}
clist_node_t *newNode = CreateNode(data);
clist_node_t *p;
for (p = *ppFirst; p->Next != pPos; p = p->Next)
{
} // 找到pos前的一个节点
p->Next = newNode; // 改变的是字段内的值,而不是指针的值
newNode->Next = pPos;
}
/**
* @brief 按位置插入
* @param {clist_node_t} **ppFirst 指向链表头节点的指针
* @param {int32_t} Pos 插入位置
* @param {cnode} data 要插入的节点数据
* @return {int32_t} 插入成功返回1否则返回0
* @note 在指定位置插入一个新节点新节点数据为data
*/
int32_t clist_insert(clist_node_t **ppFirst, int32_t Pos, cnode data) // 按位置插入
{
clist_node_t *p = *ppFirst;
for (int32_t i = 0; i < Pos; i++)
{
if (p == NULL)
return 0;
p = p->Next;
}
clist_insert_for_node(ppFirst, p, data);
return 1;
}
/**
* @brief 按位置删除
* @param {clist_node_t} **ppFirst 指向链表头节点的指针
* @param {int32_t} Pos 要删除的节点位置
* @return {int32_t} 删除成功返回1否则返回0
* @note 从指定位置删除一个节点
*/
int32_t cListErase(clist_node_t **ppFirst, int32_t Pos)
{
clist_node_t *p = *ppFirst;
for (int32_t i = 0; i < Pos; i++)
{
if (p == NULL)
return 0;
p = p->Next;
}
clist_erase_for_node(ppFirst, p);
return 1;
}
/**
* @brief 删除给定结点之后的所有结点
* @param {clist_node_t **} ppFirst 指向链表头结点的指针
* @param {clist_node_t *} pPos 要删除的结点
* @return void
* @note
*/
void clist_erase_for_node(clist_node_t **ppFirst, clist_node_t *pPos)
{
if (*ppFirst == pPos)
{
clist_pop_front(ppFirst);
return;
}
clist_node_t *p = *ppFirst;
while (p->Next != pPos)
p = p->Next;
p->Next = pPos->Next;
osel_mem_free(pPos);
}
/**
* @brief 删除指定值的结点
* @param {clist_node_t **} ppFirst 指向链表头结点的指针
* @param {cnode} data 要删除的结点数据
* @return void
* @note
*/
void clist_remove(clist_node_t **ppFirst, cnode data)
{
clist_node_t *p = *ppFirst;
clist_node_t *prev = NULL;
DBG_ASSERT(ppFirst != NULL __DBG_LINE);
if (*ppFirst == NULL)
return;
while (p)
{
if (p->data == data)
{
if (*ppFirst == p) // 删除的是第一个节点
{
*ppFirst = p->Next;
osel_mem_free(p);
p = NULL;
}
else // 删除中间节点
{
prev->Next = p->Next;
osel_mem_free(p);
p = NULL;
}
break;
}
prev = p;
p = p->Next;
}
}
/**
* @brief 删除指定值的所有结点
* @param {clist_node_t **} ppFirst 指向链表头结点的指针
* @param {cnode} data 要删除的结点数据
* @return void
* @note
*/
void clist_remove_all(clist_node_t **ppFirst, cnode data)
{
clist_node_t *p = NULL;
clist_node_t *prev = NULL;
DBG_ASSERT(ppFirst != NULL __DBG_LINE);
if (*ppFirst == NULL)
return;
p = *ppFirst;
while (p)
{
if (p->data == data)
{
if (*ppFirst == p) // 删除的是第一个节点
{
*ppFirst = p->Next;
osel_mem_free(p);
p = *ppFirst;
}
else // 删除中间节点
{
prev->Next = p->Next;
osel_mem_free(p);
p = prev;
}
}
prev = p;
p = p->Next;
}
}
/**
* @brief 销毁链表,每个节点都要销毁
* @param {clist_node_t **} ppFirst 指向链表头结点的指针
* @return void
* @note
*/
void clist_destroy(clist_node_t **ppFirst)
{
clist_node_t *p = NULL;
clist_node_t *del = NULL;
DBG_ASSERT(ppFirst != NULL __DBG_LINE);
p = *ppFirst;
while (p)
{
del = p;
p = p->Next;
osel_mem_free(del);
del = NULL;
}
*ppFirst = NULL;
}
/**
* @brief 按值查找,返回第一个找到的结点指针,如果没找到,返回 NULL
* @param {clist_node_t *} pFirst 指向链表头结点的指针
* @param {cnode} data 要查找的结点数据
* @return {clist_node_t *} 找到的结点指针,如果没有找到,返回 NULL
* @note
*/
clist_node_t *clist_find(clist_node_t *pFirst, cnode data)
{
for (clist_node_t *p = pFirst; p != NULL; p = p->Next)
{
if (p->data == data)
return p;
}
return NULL;
}