zoukankan      html  css  js  c++  java
  • RTOS双向链表数据结构

      在学习RTOS操作系统时,在任务优先级设置时用到了双向链表,说实话数据结构的东西只是停留在大学上课阶段,并未实践过,在操作系统中看得云里雾里,遂将其单独拿来了进行了一下思考,经过一个上午的摸索逐渐领会到了其中的精华。

      1.什么是双向链表

           百度百科:双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。

      

      此表中包含两个重要信息:链表结构,节点结构

      首先定义好节点的结构体:

         

    1 typedef struct _tNode
    2 {
    3     int data;
    4     struct _tNode * pre;
    5     struct _tNode * next;
    6 }tNode;

        然后在定义链表的结构体:

    1 typedef struct _tList
    2 {
    3     tNode HeadNode;
    4     int NodeCount;
    5 }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 = 0;
    }
    
    int tListCount(tList *list)//返回链表节点数量  
    {
        return list->NodeCount;
    }

        节点数据的插入和删除:

    tNode* FirstNode(tList *list)//返回首节点
    {
        tNode* node = (tNode*)0;
        if (list->NodeCount != 0)
        {
            node = list->HeadNode.next;
        }
        return node;
    }
    
    tNode* LastNode(tList *list)//返回最后一个节点
    {
        tNode* node = (tNode*)0;
        if (list->NodeCount != 0)
        {
            node = list->HeadNode.pre;
        }
        return node;
    }
    
    tNode* tListPre(tList* list,tNode* node)//返回一个节点的前一个节点
    {
        if (node->pre == node)
        {
            return (tNode*)0;
        }
        else
        {
            return node->pre;
        }
    }
    
    tNode* tListNext(tList* list, tNode* node)//返回节点的后一个节点
    {
        if (node->next == node)
        {
            return (tNode*)0;
        }
        else
        {
            return node->next;
        }
    }
    
    void RemoveAll(tList* list)//删除所有节点
    {
        tNode* CurrentNode, *NextNode;
        int count;
    
        NextNode = list->HeadNode.next;
        for (count=list->NodeCount;count > 0;count --)
        {
            CurrentNode = NextNode;
            NextNode = CurrentNode->next;
    
            CurrentNode->pre = CurrentNode;
            CurrentNode->next = CurrentNode;
        }
    
        list->HeadNode.pre = &(list->HeadNode);
        list->HeadNode.next = &(list->HeadNode);
    
        list->NodeCount = 0;
    }
    
    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 *)0;
        if (list->HeadNode.next != 0)
        {
            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 = 0;
    
        tListInit(&list);
    
        for (i = 0; i < 5; 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 = 0; i < 5; i++)
        {
            printf("%d ",node->data);
            node = node->next;
        }
        printf("
    ");
        getch();
        return 0;
    }

    实现效果为:

      在这个基础上还可以用于多种其他用处!

      PS:今天是自己第一天也是第一次写博客,在实现的过程中遇到很多问题也有很多想法,本来想一一记录但是发现写起来还是很艰辛,也许我现在就是一个小菜鸟,但是希望能够通过自己的努力一点一滴地积累逐渐成长,希望这个博客可以被我一直写下去!

                                                                                                                                                

                                                              写于广东海悟科技有限公司    2017-11-10    22:29:50

  • 相关阅读:
    charles使用
    断言
    JDBC Request
    HTTP请求建立一个测试计划
    利用badboy进行脚本录制
    接口测试用例
    Monkey常用命令
    charles安装与使用
    celery配置与基本使用
    图片验证码接口
  • 原文地址:https://www.cnblogs.com/wangshucai/p/7816762.html
Copyright © 2011-2022 走看看