一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

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

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

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

雙向循環(huán)鏈表的創(chuàng)建

C語言編程學(xué)習(xí)基地 ? 來源:C語言編程學(xué)習(xí)基地 ? 作者:C語言編程學(xué)習(xí)基地 ? 2022-05-24 16:27 ? 次閱讀

雙向循環(huán)鏈表和它名字的表意一樣,就是把雙向鏈表的兩頭連接,使其成為了一個(gè)環(huán)狀鏈表。只需要將表中最后一個(gè)節(jié)點(diǎn)的next指針指向頭節(jié)點(diǎn),頭節(jié)點(diǎn)的prior指針指向尾節(jié)點(diǎn),鏈表就能成環(huán)兒,如圖所示:

c0a72b46-db39-11ec-ba43-dac502259ad0.jpg

需要注意的是,雖然雙向循環(huán)鏈表成環(huán)狀,但本質(zhì)上還是雙向鏈表,因此在雙向循環(huán)鏈表中,依然能夠找到頭指針和頭節(jié)點(diǎn)等。雙向循環(huán)鏈表和雙向鏈表相比,唯一的不同就是雙向循環(huán)鏈表首尾相連,其他都完全一樣。

注意:因?yàn)槲疑厦嬉呀?jīng)講了雙向鏈表,所以這里只注重講他們的實(shí)現(xiàn)差異。另因?yàn)閹ь^節(jié)點(diǎn)會(huì)更好操作,所以我的代碼都有頭節(jié)點(diǎn)。

1、雙向循環(huán)鏈表的創(chuàng)建

初始化時(shí)需要將頭節(jié)點(diǎn)的next和prior都指向自己。

c0be579e-db39-11ec-ba43-dac502259ad0.jpg

//1、初始化雙向循環(huán)鏈表(帶頭節(jié)點(diǎn))

Status initLinkList(LinkList *list){

//創(chuàng)建頭節(jié)點(diǎn)

*list = malloc(sizeof(Node));

if (*list == NULL) {

return ERROR;

}

//前驅(qū)和后繼都指向自己

(*list)->prior = *list;

(*list)->data = -1;

(*list)->next = *list;

printf("已初始化鏈表~ ");

return OK;

}

2、遍歷雙向循環(huán)鏈表

注意它的尾節(jié)點(diǎn)的next不再是Null,而是頭節(jié)點(diǎn)

//2、遍歷雙向循環(huán)鏈表

void printfLinkLisk(LinkList list){

printf("遍歷鏈表: ");

if (list == NULL || list->next == list) {

printf("這是一個(gè)空鏈表 ");

return;

}

LinkList p = list;

//判斷next是否全部正確

printf("根據(jù)next從前往后遍歷:");

while (p->next != list) {

printf("%d ",p->next->data);

p = p->next;

}

printf(" ");

//判斷prior是否全部正確

printf("根據(jù)prior從后往前遍歷:");

while (p != list) {

printf("%d ",p->data);

p = p->prior;

}

printf(" ");

}

3、根據(jù)索引位置添加節(jié)點(diǎn)

這里不需要判斷尾節(jié)點(diǎn)的next是否為Null,因?yàn)樗鼤?huì)指向頭節(jié)點(diǎn)。

//3、根據(jù)索引位置插入數(shù)據(jù)至鏈表中

Status insertLinkList(LinkList *list, int index, ElemType data){

if (list == NULL || index < 0) {

return ERROR;

}

int i = 0;

LinkList priorNode = *list;

//判斷插入的位置,這里開始位置是0,index超過鏈表長度則插入末尾

while (i < index && priorNode->next != *list) {

priorNode = priorNode->next;

i++;

}

LinkList newNode = malloc(sizeof(Node));

if (newNode == NULL) {

return ERROR;

}

newNode->data = data;

//插入操作共四步,看好了,別眨眼

//1.將priorNode->next節(jié)點(diǎn)的前驅(qū)指向新節(jié)點(diǎn)

priorNode->next->prior = newNode;

//2.將新節(jié)點(diǎn)->next指向原來的priorNode->next

newNode->next = priorNode->next;

//3.將priorNode->next指向新節(jié)點(diǎn)

priorNode->next = newNode;

//4.新節(jié)點(diǎn)的前驅(qū)指向priorNode

newNode->prior = priorNode;

return OK;

}

4、根據(jù)索引位置刪除節(jié)點(diǎn)

這里不需要判斷尾節(jié)點(diǎn)的next是否為Null,因?yàn)樗鼤?huì)指向頭節(jié)點(diǎn)。

//4、根據(jù)索引位置刪除節(jié)點(diǎn)

Status deleteLinkListByIndex(LinkList *list, int index, ElemType *data){

if (*list == NULL || index < 0) {

return ERROR;

}

LinkList locaNode = *list;

int i = 0;

//注意別刪了頭節(jié)點(diǎn)

while (i <= index) {

locaNode = locaNode->next;

if (locaNode == *list) {

printf("沒有這個(gè)你想要?jiǎng)h除的節(jié)點(diǎn) ");

return ERROR;

}

i++;

}

//開始刪除,只需要做兩步

locaNode->prior->next = locaNode->next;

locaNode->next->prior = locaNode->prior;

*data = locaNode->data;

free(locaNode);

return OK;

}

5、根據(jù)存儲(chǔ)的值刪除節(jié)點(diǎn)

這里不需要判斷尾節(jié)點(diǎn)的next是否為Null,因?yàn)樗鼤?huì)指向頭節(jié)點(diǎn)。

//5、根據(jù)存儲(chǔ)的值刪除節(jié)點(diǎn)

Status deleteLinkListByData(LinkList *list, ElemType data){

if (*list == NULL) {

return ERROR;

}

LinkList locaNode = (*list)->next;

while (locaNode != *list) {

if (locaNode->data == data) {

break;

}

locaNode = locaNode->next;

}

if (locaNode == *list) {

printf("沒有這個(gè)你想要?jiǎng)h除的節(jié)點(diǎn) ");

return ERROR;

}

//開始刪除,只需要做兩步

locaNode->prior->next = locaNode->next;

locaNode->next->prior = locaNode->prior;

free(locaNode);

return OK;

}

6、根據(jù)值查找節(jié)點(diǎn)

尾節(jié)點(diǎn)的next可是頭節(jié)點(diǎn)哦,找到它就是最后一個(gè)了。

//6、查找元素

Status selectNode(LinkList list, ElemType data, LinkList *locaNode){

if (list == NULL) {

return ERROR;

}

LinkList p = list->next;

while (p != list) {

if (p->data == data) {

*locaNode = p;

break;

}

p = p->next;

}

if (*locaNode == NULL) {

printf("沒有這個(gè)你想要的節(jié)點(diǎn) ");

return ERROR;

}

else {

return OK;

}

}

其它代碼

#include "stdlib.h"

#define OK 1

#define ERROR 0

//元素類型

typedef int ElemType;

//狀態(tài)類型

typedef int Status;

//定義節(jié)點(diǎn)結(jié)構(gòu)體

typedef struct Node {

struct Node *prior;

ElemType data;

struct Node *next;

} Node;

typedef Node *LinkList;

int main(int argc, const char * argv[]) {

LinkList list;

initLinkList(&list);

for (int i = 0; i < 10; i ++) {

insertLinkList(&list, i, i);

}

printfLinkLisk(list);

int index, data;

printf("輸入你想插入的位置(從0開始)和存儲(chǔ)的值:");

scanf("%d %d",&index,&data);

insertLinkList(&list, index, data);

printfLinkLisk(list);

printf("輸入你想刪除的位置(從0開始):");

scanf("%d",&index);

deleteLinkListByIndex(&list, index, &data);

printfLinkLisk(list);

printf("輸入你想刪除的節(jié)點(diǎn)的值(只刪最前的那個(gè)):");

scanf("%d",&data);

deleteLinkListByData(&list, data);

printfLinkLisk(list);

printf(" ");

return 0;

}

輸出結(jié)果:

c0cf2b46-db39-11ec-ba43-dac502259ad0.jpg

—END—

審核編輯 :李倩

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

    關(guān)注

    0

    文章

    220

    瀏覽量

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

    關(guān)注

    0

    文章

    80

    瀏覽量

    10762

原文標(biāo)題:【C語言教程】“雙向循環(huán)鏈表”學(xué)習(xí)總結(jié)及其代碼實(shí)現(xiàn)!

文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學(xué)習(xí)基地】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

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

    技術(shù)干貨驛站 ▏深入理解C語言:嵌套循環(huán)循環(huán)控制的底層原理

    大家好!在上一節(jié)中,我們學(xué)習(xí)了C語言中的基本循環(huán)語句,如for、while和do...while循環(huán)。今天,我們將進(jìn)一步探討嵌套循環(huán)循環(huán)控制,這些技巧可以幫助我們實(shí)現(xiàn)更復(fù)雜的邏輯操作
    的頭像 發(fā)表于 02-21 18:26 ?356次閱讀
    技術(shù)干貨驛站  ▏深入理解C語言:嵌套<b class='flag-5'>循環(huán)</b>與<b class='flag-5'>循環(huán)</b>控制的底層原理

    可靠性溫度循環(huán)試驗(yàn)至少需要幾個(gè)循環(huán)

    溫度循環(huán)作為自然環(huán)境的模擬,可以考核產(chǎn)品在不同環(huán)境條件下的適應(yīng)能力,常用于產(chǎn)品在開發(fā)階段的型式試驗(yàn)、元器件的篩選試驗(yàn)。一、溫度循環(huán)測試介紹溫度循環(huán)試驗(yàn),也稱為熱循環(huán)試驗(yàn)、高低溫
    的頭像 發(fā)表于 01-23 15:26 ?336次閱讀
    可靠性溫度<b class='flag-5'>循環(huán)</b>試驗(yàn)至少需要幾個(gè)<b class='flag-5'>循環(huán)</b>?

    雙向開關(guān)電源怎么接

    雙向開關(guān)電源是一種能夠?qū)⒔涣麟姡ˋC)轉(zhuǎn)換為直流電(DC),并且能夠?qū)⒅绷麟姺聪蜣D(zhuǎn)換回交流電的電源設(shè)備。這種電源廣泛應(yīng)用于各種電子設(shè)備中,如手機(jī)充電器、筆記本電腦、太陽能逆變器等。 1. 雙向
    的頭像 發(fā)表于 09-30 15:08 ?877次閱讀

    雙向變流器的工作原理是什么

    雙向變流器(Bidirectional Converter)是一種電力電子設(shè)備,它能夠?qū)崿F(xiàn)交流(AC)和直流(DC)之間的能量雙向轉(zhuǎn)換。這種設(shè)備在許多應(yīng)用中都非常有用,比如電動(dòng)汽車的充電和放電
    的頭像 發(fā)表于 09-21 09:49 ?2335次閱讀

    智能電表雙向計(jì)量是什么意思?

    智能電表雙向計(jì)量是指智能電表能夠同時(shí)記錄電力的輸入和輸出數(shù)據(jù),即不僅能夠計(jì)量用戶消耗的電力,還能計(jì)量用戶向電網(wǎng)輸送的電力。本文將詳細(xì)探討智能電表雙向計(jì)量的功能、技術(shù)實(shí)現(xiàn)及其應(yīng)用場景。一、雙向計(jì)量
    的頭像 發(fā)表于 09-13 17:28 ?1214次閱讀
    智能電表<b class='flag-5'>雙向</b>計(jì)量是什么意思?

    雙向TVS管符號的區(qū)別

    雙向TVS管(Bidirectional Transient Voltage Suppressor)是一種用于保護(hù)電子設(shè)備免受瞬態(tài)電壓沖擊的半導(dǎo)體器件。它具有快速響應(yīng)時(shí)間和高浪涌承受能力,廣泛應(yīng)用
    的頭像 發(fā)表于 08-01 10:10 ?1890次閱讀

    雙向tvs有正負(fù)極嗎安全嗎

    有正負(fù)極,是安全的。雙向TVS(Transient Voltage Suppressor,瞬態(tài)電壓抑制器)是一種用于保護(hù)電子設(shè)備免受電壓瞬變影響的半導(dǎo)體器件。它具有雙向導(dǎo)電特性,可以同時(shí)抑制正向
    的頭像 發(fā)表于 08-01 10:07 ?1172次閱讀

    雙向tvs管怎么測量好壞

    雙向TVS(Transient Voltage Suppressor)是一種用于保護(hù)電子設(shè)備免受瞬態(tài)電壓沖擊的半導(dǎo)體器件。雙向TVS管具有雙向導(dǎo)電特性,可以同時(shí)對正向和負(fù)向的瞬態(tài)電壓進(jìn)行保護(hù)。本文將
    的頭像 發(fā)表于 08-01 09:45 ?2830次閱讀

    rnn是遞歸神經(jīng)網(wǎng)絡(luò)還是循環(huán)神經(jīng)網(wǎng)絡(luò)

    RNN(Recurrent Neural Network)是循環(huán)神經(jīng)網(wǎng)絡(luò),而非遞歸神經(jīng)網(wǎng)絡(luò)。循環(huán)神經(jīng)網(wǎng)絡(luò)是一種具有時(shí)間序列特性的神經(jīng)網(wǎng)絡(luò),能夠處理序列數(shù)據(jù),具有記憶功能。以下是關(guān)于循環(huán)神經(jīng)網(wǎng)絡(luò)的介紹
    的頭像 發(fā)表于 07-05 09:52 ?868次閱讀

    循環(huán)神經(jīng)網(wǎng)絡(luò)算法原理及特點(diǎn)

    循環(huán)神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network,簡稱RNN)是一種具有記憶功能的神經(jīng)網(wǎng)絡(luò),能夠處理序列數(shù)據(jù)。與傳統(tǒng)的前饋神經(jīng)網(wǎng)絡(luò)(Feedforward Neural Network
    的頭像 發(fā)表于 07-04 14:49 ?1104次閱讀

    循環(huán)神經(jīng)網(wǎng)絡(luò)的基本概念

    循環(huán)神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network,簡稱RNN)是一種具有循環(huán)結(jié)構(gòu)的神經(jīng)網(wǎng)絡(luò),其核心思想是將前一個(gè)時(shí)間步的輸出作為下一個(gè)時(shí)間步的輸入,從而實(shí)現(xiàn)對序列數(shù)據(jù)的建模。本文將從
    的頭像 發(fā)表于 07-04 14:31 ?1101次閱讀

    ESP32-S3的LCD接口可以用DMA鏈表來觸發(fā)發(fā)送數(shù)據(jù)嗎?

    因?yàn)槭怯脕眚?qū)動(dòng)LED顯示屏,用原來的I2S那樣并行,通過鏈接自己組織數(shù)據(jù)列表,還是比較方便的,現(xiàn)在S3的I2S好像已經(jīng)不能并行發(fā)數(shù)據(jù)了,只能用LCD的接口了,所以想知道LCD接口的DMA能不能用鏈表來組織數(shù)據(jù)。
    發(fā)表于 06-17 07:25

    雙向晶閘管的觸發(fā)方式和用實(shí)例

    雙向晶閘管(BRT)是一種特殊的半導(dǎo)體器件,因其具有雙向導(dǎo)通性,即在正負(fù)兩個(gè)方向都能導(dǎo)通,因此在交流電路中得到了廣泛應(yīng)用。而雙向晶閘管的觸發(fā)方式則是決定其工作狀態(tài)的關(guān)鍵因素之一。本文將詳細(xì)探討
    的頭像 發(fā)表于 05-22 16:23 ?2996次閱讀

    CRC(循環(huán)冗余校驗(yàn))應(yīng)用舉例

    CRC(循環(huán)冗余校驗(yàn))應(yīng)用舉例
    的頭像 發(fā)表于 05-16 16:12 ?1696次閱讀

    OpenHarmony語言基礎(chǔ)類庫【@ohos.util.LinkedList (線性容器LinkedList)】

    LinkedList底層通過雙向鏈表實(shí)現(xiàn),雙向鏈表的每個(gè)節(jié)點(diǎn)都包含對前一個(gè)元素和后一個(gè)元素的引用。當(dāng)需要查詢元素時(shí),可以從頭遍歷,也可以從尾部遍歷,插入、刪除效率高,查詢效率低。Lin
    的頭像 發(fā)表于 05-11 16:16 ?665次閱讀
    OpenHarmony語言基礎(chǔ)類庫【@ohos.util.LinkedList (線性容器LinkedList)】