• FreeRTOS链表实现


    直接上源码分析

    void vListInitialise( List_t * const pxList )
    {

       pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );           /* 此时链表中只有一个列表项(结点) */

       pxList->xListEnd.xItemValue = portMAX_DELAY;            /* 辅助值,用来做升序 */

      pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );     

      pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd )

      pxList->uxNumberOfItems = ( UBaseType_t ) 0U;              /* 记录列表中节点的数量 */

    }

    void vListInitialiseItem( ListItem_t * const pxItem )
    {

       /* 标记此节点属于哪个列表。初始化为NULL */

      pxItem->pxContainer = NULL;

    }

    void vListInsertEnd( List_t * const pxList,
                             ListItem_t * const pxNewListItem )

    {

      ListItem_t * const pxIndex = pxList->pxIndex;      /* 先拿到这个链表的索引,网上说这个索引指向列表项的头部,但是初始化并没有这个操作 */

      pxNewListItem->pxNext = pxIndex;            /* 新插入的节点的下一个节点就是这个pxIndex节点 ,新插入的节点指向了末尾节点 */
        pxNewListItem->pxPrevious = pxIndex->pxPrevious;  /* pxIndex->pxPrevious 指向的是列表的末尾节点,pxNewListItem->pxPrevious 新插入的节点的上一个等于末尾的节点,不知道为什么要这样 */

      pxIndex->pxPrevious->pxNext = pxNewListItem;    /* pxIndex->pxPrevious->pxNext本来是指向自己,现在指向的是新节点,等于连接起来 */

      pxIndex->pxPrevious = pxNewListItem;        /* 基本操作了,链接节点 */

      pxNewListItem->pxContainer = pxList;    /* 标记状态 */

      ( pxList->uxNumberOfItems )++;    /* 节点加1,这里为什么加括号? */

    }

    void vListInsert( List_t * const pxList,
                      ListItem_t * const pxNewListItem )
    {

      ListItem_t * pxIterator;          /* 新建的节点 , 辅助值 */

      const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;    /* 就用这个新的节点值来排序 */

      if( xValueOfInsertion == portMAX_DELAY )
        {
            pxIterator = pxList->xListEnd.pxPrevious;      /* 如果要插入的节点的值等于最大值,那就插在End的前一个节点的位置 */
        }

      

    else

    {

      /*  首先pxIterator指向此链表的最后一个节点,判断新插入的节点的值和pxIterator下一个节点的值

          此时 pxIterator->pxNext->xItemValue就是首节点的值,(为什么是首节点,因为初始化pxIterator指向了End节点,pxIterator = ( ListItem_t * ) &( pxList->xListEnd ))

        如果插入的值大于pxIterator->pxNext->xItemValue(第一次是首节点的值),那么pxIterator=pxIterator->pxNext ,即指向下一个节点继续循环

        如果插入的值小于pxIterator->pxNext->xItemValue,那么就说明找到了要插入的地方

        那就是新插入的到pxIterator的后面,要插入的节点就是pxIterato和 pxIterato->next之间。

        */

      for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) {  }

    }

       pxNewListItem->pxNext = pxIterator->pxNext;  /* 首先把 pxIterator->pxNext 赋值给 pxNewListItem->pxNext,让新列表项指向原本列表中下一个列表项 */

       pxNewListItem->pxNext->pxPrevious = pxNewListItem;  /*  把 pxNewListItem->pxNext(也就是原本列表中下一个列表项)的 pxNewListItem->pxNext->pxPrevious 成员指向待插入列表项 pxNewListItem,实现双向链表 */

          pxNewListItem->pxPrevious = pxIterator;    /* 新插入的上一个指向pxIterator,就是上面说的,新的节点插到pxIterator的后面 */

          pxIterator->pxNext = pxNewListItem;      /* pxIterator->pxNext : 原来的pxIterator节点  (此时只是插入节点,xIterator->pxNext一定要指向pxNewListItem,实现节点的链接)的下一个就是新的节点了 */

       pxNewListItem->pxContainer = pxList;    /* 老套路了 */  

              ( pxList->uxNumberOfItems )++; /* 列表项个数加1 */

    }

    UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )

    {

      List_t * const pxList = pxItemToRemove->pxContainer;    /* 得到要删除节点链表 */

      pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;  /* 这里就只是改变指针前后链接 */

      pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;

      mtCOVERAGE_TEST_DELAY();    /* 这里为什么要存在空函数? */

      if( pxList->pxIndex == pxItemToRemove )    /* 很好理解,不做解释 */
        {
            pxList->pxIndex = pxItemToRemove->pxPrevious;
        }

      pxItemToRemove->pxContainer = NULL;    /* 已经都删除节点了,这个节点的属主链表肯定不存在啊 */
         ( pxList->uxNumberOfItems )--;      /* 老套路了 */

      return pxList->uxNumberOfItems;    /* 返回这个链表还有几个节点 */

    }

    // 仍有疑问,希望有人看到能解答一下,在下感激不尽。

    邮箱:422705581@qq.com
  • 相关阅读:
    枚举类型(C#)
    如何在Delphi中安装组件
    操作系统知识点总结
    Java内部类学习笔记
    计算机网络笔试面试常考考点
    电话号码分身问题
    最长下降/上升子序列问题
    LeetCode(162):Find Peak Element
    LeetCode(153):Find Minimum in Rotated Sorted Array
    LeetCode(75):Sort Colors
  • 原文地址:https://www.cnblogs.com/yangdh/p/13839042.html
Copyright © 2020-2023  润新知