FreeRTOS源码解析(单向链表)
1.链表基础知识点
1.1链表的基础结构
什么是链表?
链表是一种线性数据结构,每个元素(节点)包含两个部分:
- 数据(data)
- 指向下一个节点的指针(next)
typedef struct node
{
int data;
struct node* PNext;
}Node;
链表不使用连续的内存空间,适合频繁插入/删除的场景。
单向链表 |
每个节点只包含指向 下一个 节点的指针 |
双向链表 |
每个节点包含指向 上一个 和 下一个 节点的指针 |
循环链表 |
最后一个节点指向头节点,形成环状结构 |
双向循环链表 |
双向链表 + 尾节点的
指向头节点,头节点的
指向尾节点 |
1.2链表添加节点
尾部添加:
通过malloc函数创建节点,节点的地址不连续,通过PNext指针指向下一个节点。
HeadNode ↓ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌──────┐ │ data: 0 │ →→→ │ data: 10 │ →→→ │ data: 20 │ →→→ │ NULL │ │ PNext: * │ │ PNext: * │ │ PNext: * │ └──────┘ └───────────┘ └───────────┘ └───────────┘
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node
{
int data; // 节点存放的数据
struct node* PNext; // 指向下一个节点的指针
} Node;
// 初始化链表头结点
void Init_List(Node* ListHead)
{
ListHead->data = 0; // 头结点不存放实际数据
ListHead->PNext = NULL; // 初始时没有后继节点
}
// 向链表尾部添加节点
int Add(Node* ListHead, int data)
{
Node* PNode = (Node*)malloc(sizeof(Node)); // 申请新节点内存
if (PNode == NULL) // 内存申请失败
{
return -1;
}
PNode->data = data; // 设置数据域
PNode->PNext = NULL; // 新节点的下一个为空
Node* PTemp = ListHead;
while (PTemp->PNext != NULL) // 遍历到最后一个节点
{
PTemp = PTemp->PNext;
}
PTemp->PNext = PNode; // 新节点接到链表尾部
return 0;
}
// 遍历链表并打印所有节点数据
void Traverse_List(Node* ListHead)
{
Node* PTemp = ListHead->PNext; // 从头结点的下一个开始
while (PTemp != NULL)
{
printf("%d -> ", PTemp->data); // 打印节点数据
PTemp = PTemp->PNext; // 移动到下一个节点
}
printf("NULL\n"); // 表示链表结束
}
int main(void)
{
Node HeadNode;
Init_List(&HeadNode);
// 添加几个节点
Add(&HeadNode, 10);
Add(&HeadNode, 20);
Add(&HeadNode, 30);
// 遍历链表
printf("链表内容: ");
Traverse_List(&HeadNode);
// 删除链表
Delete_List(&HeadNode);
printf("删除链表后: ");
Traverse_List(&HeadNode);
return 0;
}
1.3链表删除节点(删除指定下标的节点)
根据下标删除链表节点的本质就是:找到目标节点的前驱节点 → 修改前驱指针跳过目标节点 → 释放目标节点内存。
删除前:
HeadNode ↓ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌──────┐ │ data: 0 │ →→→ │ data: 10 │ →→→ │ data: 20 │ →→→ │ data: 30 │ →→→ │ NULL │ │ PNext: * │ │
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
嵌入式面试八股文全集 文章被收录于专栏
这是一个全面的嵌入式面试专栏。主要内容将包括:操作系统(进程管理、内存管理、文件系统等)、嵌入式系统(启动流程、驱动开发、中断管理等)、网络通信(TCP/IP协议栈、Socket编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。