IT培训机构|91免费精品视频|专注编程培训|91免费精品|软件开发培训_91免费国产视频_华清远见教育


嵌入式linux內核數據結構之單向鏈表

分享到:
           

    在嵌入式linux內核中,鏈表是一種常見的重要數據結構,它可以動態地進行存儲分配,根據需要開辟內存單元,還可以方便地實現數據的增加和刪除。鏈表中的每個元素都由兩部分組成:數據域和指針域。

    其中,數據域用于存儲數據元素的信息,指針域用于存儲該元素的直接后繼元素的位置。其整體結構就是用指針相鏈接起來的線性表,如圖1.1所示。


圖1.1 鏈表結構

    由圖中,大家可以清楚地看到,每個鏈表都有一個頭指針Head,其用于指示鏈表中第一個節點的存儲位置。之后,鏈表由第一個節點指向第二個節點,依此類推。鏈表的后一個數據元素由于沒有直接后繼節點,因此其節點的指針為空(NULL)。本文主要介紹的是單項鏈表!

    1、 單鏈表的組織與存儲

    單向鏈表的每個節點中除信息域以外還有一個指針域,用來指向其后續節點,其后一個節點的指針域為空(NULL)。

    單向鏈表由頭指針惟一確定,因此單向鏈表可以用頭指針的名字來命名,頭指針指向單向鏈表的第一個節點。

    在用C語言實現時,首先說明一個結構類型,在這個結構類型中包含一個(或多個)信息成員以及一個指針成員如下所示:

    typedef struct _link_node
    {
      element_type data; /* element_type為有效數據類型*/
      struct _link_node *next;
    } link_node;
    typedef link_node *link_list;

    鏈表結構中包含指針型的結構成員,類型為指向相同結構類型的指針。根據C語言的語法要求,結構的成員不能是結構自身類型,即結構不能自己定義自己,因為這樣將導致一個無窮的遞歸定義,但結構的成員可以是結構自身的指針類型,通過指針引用自身這種類型的結構。

    2、 單鏈表常見操作

    (1)節點初始化

    由于鏈表是一種動態分配數據的數據結構,因此單鏈表中各個節點的初始化通常使用malloc()函數,把節點中的next指針賦為NULL,同時再把數據域的部分初始化為需要的數值,通常使用memset()函數。

    int init_link(link_list *list)
    {
      /*用malloc分配函數分配節點*/
      *list = (link_list)malloc(sizeof(link_node));
      /*若分配失敗,返回*/
      if (!list)
      {
        return -1;
      }
      /*初始化鏈表節點的數據域*/
      memset(&((*list)->data), 0, sizeof(element_type));
      /*初始化鏈表節點的指針域*/
      (*list)->next = NULL;
      return 0;
    }

    (2)數據查詢

    在操作鏈表時,通常需要檢查在鏈表中是否存在某種數據,這時,可以通過順序遍歷鏈表來取得所需要的元素。

    int get_element(link_list list, int i, element_type *elem)
    {
      /* list為帶頭節點的單鏈表的頭指針 */
      /*當第i個元素存在時,其值賦給elem并返回*/
      link_list p = NULL;
      int j = 0;

      /*初始化,指向鏈表的第一個節點,j為計數器*/
      p = list->next;
      /* 為防止i過大,通過判斷p是否為空來確定是否到達鏈表的尾部 */
      while ((j++ < i) && (p = p->next));
      /* 若第i個元素不存在,返回 */
      if (!p || (j <= i))
      {
        return -1;
      }
      /*取得第i個元素*/
      *elem = p->data;
      return 0;
    }

  

    (3)鏈表的插入與刪除

    鏈表的插入與刪除是鏈表中常見的操作,也是能體現鏈表靈活性的操作。

    在單向鏈表中插入一個節點要引起插入位置前面節點的指針的變化,如圖1.2所示。


圖1.2 鏈表的節點插入過程

    由圖中可以看出,在鏈表中增加一個節點會依次完成如下操作。
    ●創建新節點C
    ●使C指向B:C→next = A→next。
    ●使A指向C:A→next = C。

    int link_insert(link_list list, int i, element_type elem)
    {
      /* list為帶頭節點的單鏈表的頭指針 */
      /* i為要插入的元素位置,elem為要插入的元素*/
      link_list p = list, new_node;
      int j = 0;

      /* 找到第i位 */
      while ((j++ < i) && (p = p->next));
      if (!p || (j <= i))
      {
        return 0;
      }
      /* 初始化鏈表節點 */
      new_node = (link_list)malloc(sizeof(link_node));
      new_node->data = elem;
      /* 將s插入鏈表,并修改原先的指針 */
      new_node->next = p->next;
      p->next = new_node;
      return 1;
    }

    刪除的過程也類似,如圖1.3所示。


圖1.3 鏈表的節點刪除過程

    同樣,鏈表中元素的指針會依次有以下變化。
    ●使A指向C:A→next = B->next。

    ●使B指向NULL:B->next = NULL 或(若不再需要該節點)釋放節點B。

    (4)其他操作

    將幾個單鏈表合并也是鏈表操作中的一個常見的操作之一。

    下面將兩個單鏈表根據標識符ID順序合并成一個單鏈表。在合并的過程中,實際上新建了一個鏈表,然后將兩個鏈表的元素依次進行比較,并且將ID較小的節點插入到新的鏈表中。如果其中一個鏈表的元素已經全部插入,則另一個鏈表的剩余操作只需順序將剩余元素插入即可。

    該過程如圖1.4所示:


圖1.4 鏈表的合并過程

    void merge_list(link_list list_a, link_list list_b, link_list *list_c)
    {
      /* 合并單鏈表list_a和list_b到list_c中 */
      link_list pa, pb, pc;

      /* 初始化pa、pb,指向鏈表的第一個元素 */
      pa = list_a->next;
      pb = list_b->next;
      *list_c = pc = list_a;
      /* 判斷兩個鏈表是否到達末尾 */
      while (pa && pb)
      {
        /*若鏈表list_a的元素小于鏈表list_b的元素,
        則把鏈表list_a的元素插入到list_c中*/
        if (less_equal_list(&pa->data, &pb->data))
        {
          pc->next = pa;
          pc = pa;
          pa = pa->next;
        }
        /* 若鏈表list_a的元素大于鏈表list_b的元素,
        則把鏈表list_b的元素插入到list_c中*/
        else
        {
          pc->next = pb;
          pc = pb;
          pb = pb->next;
        }
      }
      /* 將還未到達末尾的鏈表連入list_c中,若兩個鏈表都到達末尾,pc->next為NULL*/
      pc->next = pa?pa:pb;
    }

   熱點鏈接:

   1、Linux內核模塊程序結構
   2、嵌入式Linux內核如何編譯
   3、典型嵌入式Linux系統設置

更多新聞>> 

主站蜘蛛池模板: 网络广播_公共广播系统_校园,学校数字ip,itc智能广播系统方案 | 徐州车牌识别_徐州门禁一卡通_徐州人脸识别门禁-江苏琪瑞特智能科技有限公司 | 耐腐蚀磁力泵,直立式耐酸碱泵,立式耐酸碱泵,自吸式耐酸碱泵-杰凯泵业【官网】 | 上海珑析仪表有限公司| 重庆宏工_隧道取芯钻机_公路护栏钻机-车载式钻机_打钻一体机_护栏抢修车_隧道钻机-工程机械 | 烘干机_回转窑_破碎机_制砂机_洗砂机_球磨机-瑞光金属制品 | 消防水电施工,消防水电安装,消防水电施工公司,消防水电改造-亿杰北京消防工程公司 | 砂金设备-淘金机械-金矿选矿设备厂家-青州冠诚重工机械有限公司 砂浆生产线_干混砂浆设备_干混砂浆生产线-苏州一工机械有限公司 | 葡萄糖酸钠_食用葡萄糖_精萘-安徽鹏腾实业有限公司 | 网络舆情_网络舆情监控系统_舆情监测软件_舆情监控平台-北鲲舆情 | 中证金服投资控股(深圳)有限公司 | 太原重卡叔叔运输有限公司-山西太原大件运输、太原物流公司、太原货运物流、太原大件运输、太原货运信息、长治物流公司、长治大件运输、晋城物流公司、晋城大件运输、忻州大件运输、朔州大件运输、阳泉大件运输、大同大件运输、吕梁大件运输、临汾大件运输、运城大件运城 | 上海新航道学校官网_20年专注雅思_托福_SAT_ACT等出国语言培训机构. | 输送机|滚筒输送机|皮带输送机|滚筒|无动力滚筒|万向球生产厂家-上海霞韵输送机械设备有限公司 | 湖南九农王机电设备有限公司官网 | 斩天手游网_高质量手机游戏下载中心 | 绿夏技术导航 - 收录精选资源及优质站点网址! | 微库仑硫氯分析仪-化学发光定氮仪-X荧光硫测定仪-泰州江河仪器有限公司 | 室内儿童乐园定制_淘气堡订做_蹦床公园订制厂家-乐奇多 | 山东德曼医疗设备集团有限公司 | 河南桥式起重机-河南门式起重机-宇华起重设备集团(官网) | 中科先农农业(河北)智能设备有限责任公司 | 气象站_校园气象站_自动气象站_光伏气象站-山东万象环境科技有限公司 | 铝基板_铜基板_铝基板厂家诚之益电路—汽车灯铜基板行业制商 | 球墨井盖厂家-铸铁井盖批发-雨水篦子生产厂家-安徽含山县林头新华铸造厂 | 压瓦机|C型钢机|彩钢设备|C/Z互换檩条机-河北玉发压瓦机 | 玉米加工机械_玉米加工设备_玉米深加工机械_玉米糁加工设备--滑县鑫丰粮油机械有限公司 | 医疗器械招标网—打造医械厂家专业服务平台 | 无尘布_乳胶手套_防静电手环_口罩-苏州迈思德超净科技有限公司 | 移动厕所_真空环保厕所_环保厕所_景区生态厕所_雨施捷移动厕所生产厂家 | 友联智能|RFID应用服务供应商|专注RFID行业解决方案|RFID数据采集-助力行业数字化转型 | 轻触开关,拨动开关,德艺隆(DEALON)精密工业股份有限公司 | 耀美软瓷施工队-13638350103-专注于软瓷施工勾缝的贴软瓷施工队 - 软瓷,软瓷施工,软瓷勾缝,软瓷怎么施工,软瓷怎么勾缝,贴软瓷,软瓷施工队 | 水上游乐设备 - 郑州亿浪水上乐园设备有限公司 | 深圳PCB电路板厂|PCB线路板厂|FPC柔性电路板厂|FPC软性线路板生产厂家|恒成和电路板:18681495413 | 医盟网-全国首家医疗信息化行业门户网站 | 净水器厂家_杭州净水器厂家_杭州拥政科技有限公司 | 消防排烟风机|3C排烟风机|正压送风机|高温排烟风机|柜式排烟风机-山东锦松环境设备有限公司 | 江苏科星新材料有限公司 - 南通科星化工股份有限公司 - 南通星奇新材料有限公司 | 亚澳农机-亚澳南阳农机股份公司,旋耕机,旋播机,旋播施肥机,免耕播种机,旋耕播草多用机,果园机械-首页 | 商用厨具|商用厨房设备|商用电磁灶-鲁宝厨业官方网站 |