RTOS双向链表数据结构
在学习RTOS操作系统时,在任务优先级设置时用到了双向链表,说实话数据结构的东西只是停留在大学上课阶段,并未实践过,在操作系统中看得云里雾里,遂将其单独拿来了进行了一下思考,经过一个上午的摸索逐渐领会到了其中的精华。
1.什么是双向链表
百度百科:双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
此表中包含两个重要信息:链表结构,节点结构
首先定义好节点的结构体:
typedef struct _tNode
{
int data;
struct _tNode * pre;
struct _tNode * next;
}tNode;
然后在定义链表的结构体:
typedef struct _tList
{
tNode HeadNode;
int NodeCount;
}tList;
这个结构体的作用就是可以在工程中创建多个这样的链表结构,结构体里包含头结点HeadNode和此链表节点的数量NodeCount用来对链表进行操作的定位。头结点并不保存数据,只是提供指向节点的指针用来连接整个链表。所以在操作链表时可以很快地进行各种操作。在操作链表时只需要对完成对节点地添加和删除即可,头结点保持不变!
基本初始化:
void tNodeInit(tNode *Node)
{
Node->pre = Node;
Node->next = Node;
} void tListInit(tList *list)//初始化链表
{
list->HeadNode.pre = &(list->HeadNode);
list->HeadNode.next = &(list->HeadNode);
list->NodeCount = ;
} int tListCount(tList *list)//返回链表节点数量
{
return list->NodeCount;
}
节点数据的插入和删除:
tNode* FirstNode(tList *list)//返回首节点
{
tNode* node = (tNode*);
if (list->NodeCount != )
{
node = list->HeadNode.next;
}
return node;
} tNode* LastNode(tList *list)//返回最后一个节点
{
tNode* node = (tNode*);
if (list->NodeCount != )
{
node = list->HeadNode.pre;
}
return node;
} tNode* tListPre(tList* list,tNode* node)//返回一个节点的前一个节点
{
if (node->pre == node)
{
return (tNode*);
}
else
{
return node->pre;
}
} tNode* tListNext(tList* list, tNode* node)//返回节点的后一个节点
{
if (node->next == node)
{
return (tNode*);
}
else
{
return node->next;
}
} void RemoveAll(tList* list)//删除所有节点
{
tNode* CurrentNode, *NextNode;
int count; NextNode = list->HeadNode.next;
for (count=list->NodeCount;count > ;count --)
{
CurrentNode = NextNode;
NextNode = CurrentNode->next; CurrentNode->pre = CurrentNode;
CurrentNode->next = CurrentNode;
} list->HeadNode.pre = &(list->HeadNode);
list->HeadNode.next = &(list->HeadNode); list->NodeCount = ;
} void tListHeadAdd(tList *list,tNode *node)//在头部添加节点
{
node->next = list->HeadNode.next;
node->pre = list->HeadNode.next->pre; list->HeadNode.next = node;
list->HeadNode.next->pre = node; list->NodeCount ++; } void tListLastAdd(tList *list,tNode *node)//在最后添加节点
{
node->pre = list->HeadNode.pre;
node->next = list->HeadNode.pre->next; list->HeadNode.pre->next = node;
list->HeadNode.pre = node; list->NodeCount ++;
} tNode* RemoveFirstNode(tList *list)//移除第一个节点
{
tNode *node = (tNode *);
if (list->HeadNode.next != )
{
node = list->HeadNode.next; node->next->pre = &(list->HeadNode);
list->HeadNode.next = node->next; list->NodeCount --; free(node);
}
else
{
return node;
}
} void tListInsertAfter(tList * list, tNode * nodeAfter, tNode * nodeToInsert)//在一个节点后添加一个节点
{
nodeToInsert->next = nodeAfter->next;
nodeToInsert->pre = nodeAfter; nodeAfter->next->pre = nodeToInsert;
nodeAfter->next = nodeToInsert; list->NodeCount ++;
} void tListRemove(tList * list, tNode * node)//移除节点
{
node->pre->next = node->next;
node->next->pre = node->pre; free(node); list->NodeCount --; }
在这个双向链表的实现过程中可以很好地实现队列操作,先进先出概念如这样验证:
int main()
{
tList list;
tNode *node;
int i = ; tListInit(&list); for (i = ; i < ; i++)
{
node = (tNode*)malloc(sizeof(tNode)); printf("Please input the number:");
scanf_s("%d",&node->data); tListLastAdd(&list, node);
} node = FirstNode(&list); printf("List is:");
for (i = ; i < ; i++)
{
printf("%d ",node->data);
node = node->next;
}
printf("\n");
getch();
return ;
}
实现效果为:
在这个基础上还可以用于多种其他用处!
PS:今天是自己第一天也是第一次写博客,在实现的过程中遇到很多问题也有很多想法,本来想一一记录但是发现写起来还是很艰辛,也许我现在就是一个小菜鸟,但是希望能够通过自己的努力一点一滴地积累逐渐成长,希望这个博客可以被我一直写下去!
写于广东海悟科技有限公司 2017-11-10 22:29:50
RTOS双向链表数据结构的更多相关文章
- Linux 内核里的数据结构:双向链表
原文:https://blog.csdn.net/qq_33487044/article/details/78827260 双向链表 Linux 内核自己实现了双向链表,可以在 include/lin ...
- 常用数据结构-线性表及Java 动态数组 深究
[Java心得总结六]Java容器中——Collection在前面自己总结的一篇博文中对Collection的框架结构做了整理,这里深究一下Java中list的实现方式 1.动态数组 In compu ...
- 浅谈java类集框架和数据结构(2)
继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主 ...
- Java核心数据结构(List,Map,Set)原理与使用技巧
JDK提供了一组主要的数据结构实现,如List.Map.Set等常用数据结构.这些数据都继承自 java.util.Collection 接口,并位于 java.util 包内. 1.List接口 最 ...
- 【转】Java学习---Java核心数据结构(List,Map,Set)使用技巧与优化
[原文]https://www.toutiao.com/i6594587397101453827/ Java核心数据结构(List,Map,Set)使用技巧与优化 JDK提供了一组主要的数据结构实现, ...
- 双向链表-java完全解析
原文:https://blog.csdn.net/nzfxx/article/details/51728516 "双向链表"-数据结构算法-之通俗易懂,完全解析 1.概念的引入 相 ...
- Java核心数据结构(List、Map、Set)原理与使用技巧
JDK提供了一组主要的数据结构实现,如List.Set等常用数据结构.这些数据都继承自java.util.Collection接口,并位于java.util包内. 一.List接口 最重要的三种Lis ...
- 你真的懂Redis的5种基本数据结构吗?
摘要: 你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看. 本文分享自华为云社区<你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看>,作者:李子捌. 一 ...
- [数据结构]链表相关的实现LinkList.cpp
目录 LinkList.cpp //链表相关操作的实现 LinkList.h LinkListManager.cpp //链表相关实现函数的调用 LinkListManager.h LinkList. ...
随机推荐
- MyBatis一对一查询
---------------------siwuxie095 MyBatis 一对一查询 以订单和用户为例,即 相对订 ...
- 兼容主流浏览器的css渐变色
网页中的渐变色区域,渐变色背景,一般都是通过ps图片方法来实现,但是图片放得多了会影响网页的打开速度,本文介绍的就是用纯 CSS 实现 IE .Firefox.Chrome 和 和Safari都支持的 ...
- BZOJ1221 [HNOI2001]软件开发 - 费用流
题解 非常显然的费用流. 但是建图还是需要思考的QuQ 将每天分成两个节点 $x_{i,1}, x_{i,2} $, $ x_{i,1}$用于提供服务, $x_{i ,2}$ 用来从源点获得$nd[i ...
- NFS 挂载 + autofs
NFS:Network File System RPC:Remote Procedure Call 一.手动挂载 (mount -t nfs 服务端IP:/共享目录 /本地挂载点) 客户端 1.安 ...
- pyqt5和qtdesign的使用
http://blog.csdn.net/Angelasan/article/details/44917283 发现我的使用时候有点跟他不同. 我是 g: utf- -*- # Form implem ...
- centos7 rabbitmq安装以及应用
安装单机rabbitmq 1.安装erlang cd /usr.local yum install wget yum install net-tools wget http://erlang.or ...
- 如何优化Mysql数据库
1.添加主键ID 2.尽量避免使用select * form table 3.创建索引 对于查询占主要的应用来说,索引显得尤为重要.很多时候性能问题很简单的就是因为我们忘了添加索引而造成的,或 ...
- 2018.10.16 NOIP模拟 华莱士(并查集)
传送门 按照题意模拟维护最小的环套树森林就行了. 然而考试的时候naivenaivenaive瞎写了一个错误的贪心. 代码
- 2018.09.01 独立集(树形dp)
描述 给定一颗树(边权为1),选取一个节点子集,使得该集合中任意两个节点之间的距离都大于K.求这个集合节点最多是多少 输入 第一行是两个整数N,K 接下来是N-1行,每行2个整数x,y,表示x与y有一 ...
- 2018.08.29 NOIP模拟 pmatrix(线性筛)
[问题描述] 根据哥德巴赫猜想(每个不小于 6 的偶数都可以表示为两个奇素数之和),定义 哥德巴赫矩阵 A 如下:对于正整数对(i,j),若 i+j 为偶数且 i,j 均为奇素数,则 Ai,j = 1 ...