91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

雙向循環(huán)鏈表函數(shù)是什么?如何去實(shí)現(xiàn)它?

Android編程精選 ? 來源:編程學(xué)習(xí)總站 ? 作者:寫代碼的牛頓 ? 2021-06-17 12:50 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1、雙向循環(huán)鏈表結(jié)點(diǎn)定義和函數(shù)聲明

雙向循環(huán)鏈表結(jié)點(diǎn)內(nèi)部有2個(gè)指針prev和next分別指向前后的結(jié)點(diǎn),結(jié)點(diǎn)定義代碼如下:

typedefstructdlist{ intdata; structdlist*next; structdlist*prev; }dlist_t;

現(xiàn)在我們聲明一些雙向循環(huán)鏈表操作函數(shù),代碼如下:

externdlist_t *new_dlist_node(intdata); //新建一個(gè)結(jié)點(diǎn) externdlist_t *dlist_add(dlist_t*list, intdata); //插入一個(gè)結(jié)點(diǎn) externdlist_t *dlist_delete(dlist_t*list, intindex); //刪除索引對(duì)應(yīng)的結(jié)點(diǎn)(索引從0開始) externdlist_t *dlist_index_of(dlist_t*list, intindex); //查找索引對(duì)應(yīng)的結(jié)點(diǎn) externvoiddlist_destroy(dlist_t*list); //銷毀雙向循環(huán)鏈表 externvoiddlist_print(dlist_t*list); //打印鏈表數(shù)據(jù)

可以看到很多函數(shù)都會(huì)返回一個(gè)dlist_t類型的指針,其實(shí)這是頭結(jié)點(diǎn)。很多時(shí)候?yàn)榱藭鴮懛奖阄覀儠?huì)采用typedef定義自己的數(shù)據(jù)類型,結(jié)點(diǎn)定義里為什么next和prev指針可以那樣寫,參考我上一篇文章,后面會(huì)大量這樣使用。

2、雙向循環(huán)鏈表函數(shù)實(shí)現(xiàn)

為了更方便釋放一個(gè)結(jié)點(diǎn)內(nèi)存,我們定義了一個(gè)文件作用域靜態(tài)函數(shù)free_dlist_node。

voidfree_dlist_node(dlist_t*node){ if(node == NULL){ return; } node->next = NULL; node->prev = NULL; free(node); node = NULL; }

該函數(shù)只負(fù)責(zé)釋放內(nèi)存的操作。

新建鏈表結(jié)點(diǎn)

dlist_t*new_dlist_node(intdata){ dlist_t*node = (dlist_t*)malloc(sizeof(dlist_t)); if(node == NULL){ returnNULL; } node->data = data; node->next = node; node->prev = node; returnnode; }

這里我們主要注意一點(diǎn)就是新建立的結(jié)點(diǎn)next和prev指針會(huì)初始化為指向自身,事實(shí)上雙向循環(huán)鏈表頭結(jié)點(diǎn)必須這樣初始化才能更好的利用雙向循環(huán)鏈表特性執(zhí)行插入、刪除和查詢等操作。

插入結(jié)點(diǎn)

dlist_t *dlist_add(dlist_t *list, int data){ if(list== NULL){ returnNULL; } //新建一個(gè)結(jié)點(diǎn) dlist_t *node = new_dlist_node(data); if(node == NULL){ returnlist; } //將結(jié)點(diǎn)插入雙向循環(huán)鏈表 list->prev->next = node; //最后的結(jié)點(diǎn)next指針指向node node->next = list; //node的next指針指向頭結(jié)點(diǎn) node->prev = list->prev; //node的prev指針指向原尾結(jié)點(diǎn) list->prev = node; //頭結(jié)點(diǎn)的prev指針指向新尾結(jié)點(diǎn) returnlist; }

這里list是傳入的頭結(jié)點(diǎn),我們采用尾插法插入一個(gè)結(jié)點(diǎn),最后返回頭結(jié)點(diǎn)。這里需要注意:每次插入結(jié)點(diǎn)都要更新頭結(jié)點(diǎn)的prev指針。

刪除指定位置的結(jié)點(diǎn)

dlist_t *dlist_delete(dlist_t *list, int index){ if(list== NULL|| index < 0){ ????????return?list; ????} ????dlist_t *head = list; ????int list_index = 0; ????//刪除鏈表頭結(jié)點(diǎn) ????if(index == 0){ ????????//鏈表只有一個(gè)結(jié)點(diǎn) ????????if(head == list->next){ free_dlist_node(list); list= NULL; returnNULL; }else{ //鏈表有大于1個(gè)結(jié)點(diǎn) head = head->next; //頭結(jié)點(diǎn)往后移一個(gè) head->prev = list->prev; //頭結(jié)點(diǎn)的prev指向尾部結(jié)點(diǎn) list->prev->next = head; //尾部結(jié)點(diǎn)的next指針指向頭結(jié)點(diǎn) free_dlist_node(list); //釋放結(jié)點(diǎn)內(nèi)存 returnhead; } } list= list->next; list_index++; //查詢目標(biāo)結(jié)點(diǎn),通過檢查當(dāng)前結(jié)點(diǎn)是否是頭結(jié)點(diǎn)判斷是否已經(jīng)把雙線循環(huán)鏈表遍歷了一遍 while(list_index < index && head != list){ ????????list?= list->next; list_index++; } //沒有找到即將刪除的結(jié)點(diǎn) if(head == list){ returnhead; } //找到即將刪除的結(jié)點(diǎn) else{ list->prev->next = list->next; //目標(biāo)結(jié)點(diǎn)的上一個(gè)結(jié)點(diǎn)的next指針指向目標(biāo)結(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn) list->next->prev = list->prev; //目標(biāo)結(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn)的prev指針指向目標(biāo)結(jié)點(diǎn)的上一個(gè)結(jié)點(diǎn) free_dlist_node(list); //釋放結(jié)點(diǎn)內(nèi)存 returnhead; //返回頭結(jié)點(diǎn) } }

刪除結(jié)點(diǎn)一定要注意:

判斷被刪除的結(jié)點(diǎn)是否是頭結(jié)點(diǎn)

指定的位置是否超出了鏈表的長(zhǎng)度。

查找指定位置的結(jié)點(diǎn)

dlist_t*dlist_index_of(dlist_t*list, intindex){ if(list== NULL|| index < 0){ ????????return?NULL; ????} ????//如果想要獲取頭結(jié)點(diǎn),則直接返回頭結(jié)點(diǎn) ????if(index == 0){ ????????return?list; ????} ????dlist_t?*head = list; ????list?= list->next; intlist_index = 1; //遍歷鏈表查找指定的索引,通過檢查當(dāng)前結(jié)點(diǎn)是否等于頭結(jié)點(diǎn)判斷是否已遍歷完畢 while(list_index < index && list?!= head){ ????????list_index++; ????????list?= list->next; } //沒有找到索引對(duì)應(yīng)的結(jié)點(diǎn) if(list== head){ returnNULL; } //找到了索引對(duì)應(yīng)的結(jié)點(diǎn) returnlist; }

查找指定位置結(jié)點(diǎn)要注意幾個(gè)地方:

是否是頭結(jié)點(diǎn)

是否超出了鏈表長(zhǎng)度

銷毀鏈表

void dlist_destroy(dlist_t *list){ if(list== NULL){ return; } //如果只有一個(gè)結(jié)點(diǎn) if(list->next == list){ free_dlist_node(list); return; } dlist_t *temp = list; list= list->next; while(list!= temp){ list= list->next; //遍歷下一個(gè)結(jié)點(diǎn) temp->prev->next = list; list->prev = temp->prev; temp->next = NULL; temp->prev = NULL; free(temp); temp = list; } free_dlist_node(list); }

打印鏈表數(shù)據(jù)

voiddlist_print(dlist_t*list){ if(list== NULL){ return; } dlist_t*head = list; printf("%d, ", list->data); list= list->next; while(list!= head){ printf("%d, ", list->data); list= list->next; } printf(" "); }

最后我們寫個(gè)小程序驗(yàn)證一下雙向循環(huán)鏈表函數(shù)實(shí)現(xiàn)是否正確。

#include #include"dlist.h" intmain(){ dlist_t*list= new_dlist_node(2); inti = 0; for(i = 0; i < 7; i++){ ????????list?= dlist_add(list, 3?+ i); ????} ????printf("打印未處理過的完整鏈表 "); ????dlist_print(list); ????list?= dlist_delete(list, 0); //刪除第一個(gè)結(jié)點(diǎn) ????list?= dlist_delete(list, 3); //刪除第四個(gè)結(jié)點(diǎn) ????printf("打印刪除2個(gè)結(jié)點(diǎn)后的鏈表 "); ????dlist_print(list); ????dlist_t?*node = dlist_index_of(list, 2); ????printf("第3個(gè)結(jié)點(diǎn)是:%d ", node->data); printf("銷毀鏈表 "); dlist_destroy(list); list= NULL; return0; }

編譯運(yùn)行輸出:

打印未處理過的完整鏈表 2, 3, 4, 5, 6, 7, 8, 9, 打印刪除2個(gè)結(jié)點(diǎn)后的鏈表 3, 4, 5, 7, 8, 9, 第3個(gè)結(jié)點(diǎn)是:5 銷毀鏈表

驗(yàn)證完全正確。

責(zé)任編輯:lq6

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4417

    瀏覽量

    67501
  • 鏈表
    +關(guān)注

    關(guān)注

    0

    文章

    80

    瀏覽量

    11057

原文標(biāo)題:數(shù)據(jù)結(jié)構(gòu)與算法篇-雙向循環(huán)鏈表

文章出處:【微信號(hào):AndroidPush,微信公眾號(hào):Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    功率循環(huán)基礎(chǔ)篇(二) —— 功率循環(huán)壽命曲線解讀

    功率循環(huán)壽命曲線是評(píng)估功率半導(dǎo)體器件(如 ?IGBT?模塊)在溫度交變應(yīng)力下長(zhǎng)期可靠性的核心工具。該曲線通常以 結(jié)溫波動(dòng)幅度?ΔTj 為橫坐標(biāo),以器件達(dá)到指定失效判據(jù)前所經(jīng)歷的 循環(huán)次數(shù)?Nf 為
    的頭像 發(fā)表于 03-02 11:55 ?48次閱讀
    功率<b class='flag-5'>循環(huán)</b>基礎(chǔ)篇(二) —— 功率<b class='flag-5'>循環(huán)</b>壽命曲線解讀

    CS5801搭配AS721芯片實(shí)現(xiàn)HDMI轉(zhuǎn)DP雙向互轉(zhuǎn)方案

    CS5801與AS721芯片組合實(shí)現(xiàn)HDMI與DP雙向互轉(zhuǎn)。CS5801支持HDMI2.0b轉(zhuǎn)DP1.4a,提供4K@60Hz傳輸;AS721作為低功耗交換機(jī)芯片實(shí)現(xiàn)雙向信號(hào)切換。方案
    的頭像 發(fā)表于 01-21 10:20 ?223次閱讀
    CS5801搭配AS721芯片<b class='flag-5'>實(shí)現(xiàn)</b>HDMI轉(zhuǎn)DP<b class='flag-5'>雙向</b>互轉(zhuǎn)方案

    如何在Zephyr RTOS中實(shí)現(xiàn)延時(shí)和計(jì)時(shí)函數(shù)

    多種延時(shí)與計(jì)時(shí)實(shí)現(xiàn)方案,滿足不同應(yīng)用場(chǎng)景的需求。那么,大家平時(shí)都是怎么在MCU程序中實(shí)現(xiàn)計(jì)時(shí)函數(shù)、實(shí)現(xiàn)延時(shí)的呢?
    的頭像 發(fā)表于 12-26 10:32 ?5431次閱讀
    如何在Zephyr RTOS中<b class='flag-5'>實(shí)現(xiàn)</b>延時(shí)和計(jì)時(shí)<b class='flag-5'>函數(shù)</b>

    內(nèi)存拷貝函數(shù) memcpy原理及實(shí)現(xiàn)

    內(nèi)存拷貝函數(shù)memcpymemcpy是memory copy的縮寫,意為內(nèi)存復(fù)制,在寫C語言程序的時(shí)候,我們常常會(huì)用到。的函原型如下:void *memcpy(void *dest, const
    發(fā)表于 12-26 08:03

    雙向保護(hù)開關(guān)評(píng)估套件使用指南

    負(fù)載斷開。今天,我們就來詳細(xì)介紹雙向開關(guān)評(píng)估套件EVAL_BDPS_DD_TOLL/G和EVAL_BDPS_DRIVER,主要用于測(cè)試和評(píng)估MOSFET的性能。 文件下載: Infineon
    的頭像 發(fā)表于 12-20 20:35 ?1074次閱讀

    無數(shù)據(jù)域雙向鏈表的代碼

    ); return 0; } 在這個(gè)示例中,我們定義了一個(gè)包含指向前一個(gè)節(jié)點(diǎn)和后一個(gè)節(jié)點(diǎn)的結(jié)構(gòu)體 Node,以及一個(gè)包含整數(shù)數(shù)據(jù)和 Node 結(jié)構(gòu)體的結(jié)構(gòu)體 Data。然后實(shí)現(xiàn)了插入和打印鏈表函數(shù)。在打
    發(fā)表于 12-11 06:56

    實(shí)現(xiàn)一個(gè)嵌入式的軟件定時(shí)器

    所有運(yùn)行中的軟件定時(shí)器,將各個(gè)到期時(shí)間與全局時(shí)鐘標(biāo)記做比較,以判斷對(duì)應(yīng)軟件定時(shí)器是否到期,到期則執(zhí)行相應(yīng)的回調(diào)函數(shù),并關(guān)閉該定時(shí)器。 以上是單次定時(shí)器的實(shí)現(xiàn),若要實(shí)現(xiàn)周期定時(shí)器,即到期后接
    發(fā)表于 12-10 08:29

    控制流和函數(shù)調(diào)用的精細(xì)調(diào)整

    特性,避免不必要的計(jì)算。 函數(shù)調(diào)用涉及開銷,因?yàn)?b class='flag-5'>它需要保存當(dāng)前執(zhí)行環(huán)境并跳轉(zhuǎn)到新的執(zhí)行環(huán)境。減少函數(shù)調(diào)用,尤其是在頻繁執(zhí)行的循環(huán)中,可以顯著提高性能。 對(duì)于簡(jiǎn)單且頻繁調(diào)用的
    發(fā)表于 11-14 06:32

    使用函數(shù)實(shí)現(xiàn)三相電機(jī)正反轉(zhuǎn)控制

    在使用西門子S1200PLC,所使用的軟件是博途軟件,在這個(gè)軟件里運(yùn)用了塊的概念。比如我們常見的組織塊(OB)、函數(shù)塊(FB)、數(shù)據(jù)塊(DB)以及函數(shù)FC等。今天我們來具體交流一下這個(gè)函數(shù)塊(FB)的具體使用方法。
    的頭像 發(fā)表于 10-15 14:40 ?2712次閱讀
    使用<b class='flag-5'>函數(shù)</b>塊<b class='flag-5'>實(shí)現(xiàn)</b>三相電機(jī)正反轉(zhuǎn)控制

    rt_object_get_information獲取到的鏈表為空怎么解決?

    rtt啟動(dòng)過程,在初始化堆的時(shí)候,進(jìn)入rt_object_init,調(diào)用rt_object_get_information獲取到的鏈表為空,導(dǎo)致系統(tǒng)起不來。
    發(fā)表于 10-11 11:44

    人工智能行業(yè)如何使用for循環(huán)語句進(jìn)行循環(huán)

    : 支持range()函數(shù)生成數(shù)字序列 可結(jié)合else語句使用 Java中的for循環(huán): 傳統(tǒng)結(jié)構(gòu):for(初始化; 條件; 增量) 增強(qiáng)for循環(huán):for(類型 變量 : 集合) 主要用于數(shù)組和集合
    的頭像 發(fā)表于 09-10 12:55 ?564次閱讀

    如何實(shí)現(xiàn)高效雙向電能變換

    隨著電動(dòng)汽車、家庭和工商業(yè)儲(chǔ)能產(chǎn)品快速普及,雙向電能變換系統(tǒng)的熱度也在不斷攀升。作為電網(wǎng)與電池的功率橋梁,雙向電能變換系統(tǒng)基于一套硬件電路就能控制電池充放電,實(shí)現(xiàn)能量雙向流動(dòng),相比傳統(tǒng)
    的頭像 發(fā)表于 07-23 11:40 ?1553次閱讀

    什么是光伏雙向電表?雙向電表有哪些應(yīng)用?

    電能的雙向流動(dòng)軌跡。在用戶側(cè)并網(wǎng)運(yùn)行模式下,不僅計(jì)量用戶從公共電網(wǎng)獲取的用電量(正向有功電能),同時(shí)精準(zhǔn)統(tǒng)計(jì)光伏系統(tǒng)向電網(wǎng)回饋的發(fā)電量(逆向有功電能),實(shí)現(xiàn)能源流量的全維度監(jiān)控。 技術(shù)支持 安科瑞 程瑜 187 0211 2087 雙向
    的頭像 發(fā)表于 05-12 09:42 ?2187次閱讀
    什么是光伏<b class='flag-5'>雙向</b>電表?<b class='flag-5'>雙向</b>電表有哪些應(yīng)用?

    函數(shù)指針的六個(gè)常見應(yīng)用場(chǎng)景

    函數(shù)指針在嵌入式開發(fā)中有著廣泛的應(yīng)用,讓代碼更加靈活,減少冗余,提高可擴(kuò)展性。很多時(shí)候,我們需要根據(jù)不同的情況動(dòng)態(tài)調(diào)用不同的函數(shù),而函數(shù)指針正是實(shí)
    的頭像 發(fā)表于 04-07 11:58 ?1475次閱讀
    <b class='flag-5'>函數(shù)</b>指針的六個(gè)常見應(yīng)用場(chǎng)景

    給uint32_t數(shù)組填充整型值,除使用循環(huán)賦值外有沒有c庫(kù)函數(shù)可以實(shí)現(xiàn)

    給uint32_t數(shù)組填充整型值,除使用循環(huán)賦值外有沒有c庫(kù)函數(shù)可以實(shí)現(xiàn)
    發(fā)表于 03-07 17:05