在学习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双向链表数据结构的更多相关文章

  1. Linux 内核里的数据结构:双向链表

    原文:https://blog.csdn.net/qq_33487044/article/details/78827260 双向链表 Linux 内核自己实现了双向链表,可以在 include/lin ...

  2. 常用数据结构-线性表及Java 动态数组 深究

    [Java心得总结六]Java容器中——Collection在前面自己总结的一篇博文中对Collection的框架结构做了整理,这里深究一下Java中list的实现方式 1.动态数组 In compu ...

  3. 浅谈java类集框架和数据结构(2)

    继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主 ...

  4. Java核心数据结构(List,Map,Set)原理与使用技巧

    JDK提供了一组主要的数据结构实现,如List.Map.Set等常用数据结构.这些数据都继承自 java.util.Collection 接口,并位于 java.util 包内. 1.List接口 最 ...

  5. 【转】Java学习---Java核心数据结构(List,Map,Set)使用技巧与优化

    [原文]https://www.toutiao.com/i6594587397101453827/ Java核心数据结构(List,Map,Set)使用技巧与优化 JDK提供了一组主要的数据结构实现, ...

  6. 双向链表-java完全解析

    原文:https://blog.csdn.net/nzfxx/article/details/51728516 "双向链表"-数据结构算法-之通俗易懂,完全解析 1.概念的引入 相 ...

  7. Java核心数据结构(List、Map、Set)原理与使用技巧

    JDK提供了一组主要的数据结构实现,如List.Set等常用数据结构.这些数据都继承自java.util.Collection接口,并位于java.util包内. 一.List接口 最重要的三种Lis ...

  8. 你真的懂Redis的5种基本数据结构吗?

    摘要: 你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看. 本文分享自华为云社区<你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看>,作者:李子捌. 一 ...

  9. [数据结构]链表相关的实现LinkList.cpp

    目录 LinkList.cpp //链表相关操作的实现 LinkList.h LinkListManager.cpp //链表相关实现函数的调用 LinkListManager.h LinkList. ...

随机推荐

  1. TZOJ 1545 Hurdles of 110m(01背包dp)

    描述 In the year 2008, the 29th Olympic Games will be held in Beijing. This will signify the prosperit ...

  2. jquery 赋值时不触发change事件解决

    $("#optionsId").change(function(){ $("#selectOptionsText").val('测试'); }); $(&quo ...

  3. runloop - 面试题

    2.

  4. 10-多写一个@Autowired导致程序崩了

    再是javaweb实验六中,是让我们改代码,让它跑起来,结果我少注释了一个,导致一直报错,检查许久没有找到,最后通过代码替换逐步查找,才发现问题.

  5. linux 下 php 安装 event

    1.下载event源码包 https://pecl.php.net/package/event 如:event-2.0.4.tgz 2.解压 > tar zxvf event-2.0.4.tgz ...

  6. JTSL/EL Expression学习

    最早的一个学习笔记,时间过去了久了,供java web初学者参考. JTSL/EL Expression学习安排 学习目标:掌握几个常见标签的使用,通晓工作原理,详细到代码层面,遇到问题时能查得出异常 ...

  7. linux下添加用户并赋予root权限

    1.添加用户,首先用adduser命令添加一个普通用户,命令如下: #adduser tommy //添加一个名为tommy的用户#passwd tommy   //修改密码Changing pass ...

  8. bluez蓝牙测试工具

    http://blog.csdn.net/talkxin/article/details/50610984

  9. asp.net (jquery easy-ui datagrid)通用Excel文件导出(NPOI)

    http://www.cnblogs.com/datacool/archive/2013/03/12/easy-ui_datagrid_export_excel_asp_net.html

  10. DataStage 八、清除日志

    DataStage序列文章 DataStage 一.安装 DataStage 二.InfoSphere Information Server进程的启动和停止 DataStage 三.配置ODBC Da ...