国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

雙向鏈表(Double Linked List)

這篇具有很好參考價值的文章主要介紹了雙向鏈表(Double Linked List)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、簡介

? ? ? ? 雖然單向鏈表能夠100%解決邏輯關(guān)系為“一對一”數(shù)據(jù)的存儲問題,但在解決那些需要大量查找前趨節(jié)點的問題是,單向鏈表無疑是不能用了,因為單向鏈表適合“從前往后”查找,并不適合“從后往前”查找。

? ? ? ? 如果要提高鏈表的查找效率,那雙向鏈表(雙鏈表)無疑是首選。

? ? ? ? 雙向鏈表字面上的意思是“雙向”的鏈表,如圖1所示。

雙向鏈表(Double Linked List)
圖1 - 雙向鏈表示意圖

??? ? ? 雙向指各個節(jié)點之間的邏輯關(guān)系是雙向的,該鏈表通常只有一個頭節(jié)點。

? ? ? ? 從圖1還可以看出,雙向鏈表中每個節(jié)點包括一下3個部分,分別是指針域(用于指向當(dāng)前節(jié)點的直接前驅(qū)節(jié)點)、數(shù)據(jù)域(用于存儲數(shù)據(jù)元素)和指針域(用于指向當(dāng)前節(jié)點的后繼節(jié)點)。

二、創(chuàng)建

1、聲明

typedef struct line{
    struct line *prior;//指向直接前趨
    int data;
    struct line *next;//指向直接后繼
}line;

2、創(chuàng)建

line* initLine(line *head){
    head=(line*)malloc(sizeof(line));//創(chuàng)建鏈表第一個結(jié)點(首元結(jié)點)
    head->prior=NULL;
    head->next=NULL;
    head->data=1;
    line *list=head;
    for(int i=2; i<=3; i++)
    {
        //創(chuàng)建并初始化一個新結(jié)點
        line *body=(line*)malloc(sizeof(line));
        body->prior=NULL;
        body->next=NULL;
        body->data=i;

        list->next=body;//直接前趨結(jié)點的next指針指向新結(jié)點
        body->prior=list;//新結(jié)點指向直接前趨結(jié)點
        list=list->next;
    }
    return head;
}

三、基本操作

1、添加節(jié)點

? ? ? ? 添加節(jié)點可以分為三種,分別是:添加至表頭、添加至鏈表的中間位置添加至鏈表尾。

添加至表頭

? ? ? ? 將新元素添加到表頭,只需要將其與表頭元素建立雙層邏輯關(guān)系即可。

? ? ? ? 假設(shè)定義新元素節(jié)點為tmp,表頭節(jié)點為head,則只需要執(zhí)行下面兩個步驟和即可:

  1. tmp的next變成head,head的prior編程tmp;
  2. 將head移至tmp,重新指向新的表頭。

????????比如將元素7天添加到雙向鏈表的表頭,則實現(xiàn)過程如圖2所示。

雙向鏈表(Double Linked List)
圖2 - 添加元素至雙向鏈表的表頭

添加至鏈表的中間位置

? ? ? ? 添加至表的中間位置主要分為兩個步驟:

  1. 新節(jié)點先與其后繼節(jié)點建立雙層邏輯關(guān)系;
  2. 新節(jié)點的前驅(qū)與之建立雙層邏輯關(guān)系。

? ? ? ? ?此過程如圖3所示。

雙向鏈表(Double Linked List)
圖3 - 雙向鏈表中間位置添加數(shù)據(jù)元素示意圖

?添加至表尾

?? ? ? ?與添加至表頭很相似,其過程如下:

  1. 找到雙向鏈表的最后一個節(jié)點;
  2. 讓新節(jié)點與其進行雙層邏輯關(guān)系建立。

? ? ? ? 此過程如圖4所示。?

雙向鏈表(Double Linked List)
圖4 - 雙向鏈表尾部添加元素示意圖

代碼

經(jīng)過上述內(nèi)容,我們可以試著編寫代碼了。

line *insertLine(line *head,int data,int add){
    //新建數(shù)據(jù)域為data的結(jié)點
    line *temp=(line*)malloc(sizeof(line));
    temp->data=data;
    temp->prior=NULL;
    temp->next=NULL;
    //插入到鏈表頭,要特殊考慮
    if(add==1)
    {
        temp->next=head;
        head->prior=temp;
        head=temp;
    }
    else
    {
        line *body=head;
        //找到要插入位置的前一個結(jié)點
        for(int i=1; i<add-1; i++)
        {
            body=body->next;
        }
        //判斷條件為真,說明插入位置為鏈表尾
        if(body->next==NULL)
        {
            body->next=temp;
            temp->prior=body;
        }
        else
        {
            body->next->prior=temp;
            temp->next=body->next;
            body->next=temp;
            temp->prior=body;
        }
    }
    return head;
}

2、刪除節(jié)點

? ? ? ? 雙向鏈表刪除節(jié)點時,只需要遍歷到要刪除的節(jié)點,然后將其刪除即可。

? ? ? ? 例如,從刪除2的過程如圖5所示。

雙向鏈表(Double Linked List)
圖5 - 雙向鏈表刪除元素的操作示意圖

代碼

//刪除結(jié)點的函數(shù),data為要刪除結(jié)點的數(shù)據(jù)域的值
line *delLine(line *head,int data)
{
    line *temp=head;
    //遍歷鏈表
    while(temp)
    {
        //判斷當(dāng)前結(jié)點中數(shù)據(jù)域和data是否相等,若相等,摘除該結(jié)點
        if (temp->data==data)
        {
            temp->prior->next=temp->next;
            temp->next->prior=temp->prior;
            free(temp);
            return head;
        }
        temp=temp->next;
    }
    printf("鏈表中無該數(shù)據(jù)元素");
    return head;
}

3、查找節(jié)點

? ? ? ? 依次遍歷表中數(shù)據(jù),直到找到為止。

代碼

//head為原雙鏈表,elem表示被查找元素
int selectElem(line * head,int elem){
//新建一個指針t,初始化為頭指針 head
    line * t=head;
    int i=1;
    while(t)
    {
        if(t->data==elem)
        {
            return i;
        }
        i++;
        t=t->next;
    }
    //程序執(zhí)行至此處,表示查找失敗
    return -1;
}

4、更改節(jié)點

? ? ? ? 在查找的基礎(chǔ)上完成。過程是通過遍歷找到的節(jié)點,直接將數(shù)據(jù)域修改即可。

代碼

//更新函數(shù),其中,add 表示更改結(jié)點在雙鏈表中的位置,newElem 為新數(shù)據(jù)的值
line *amendElem(line *p,int add,int newElem){
    line *temp=p;
    //遍歷到被刪除結(jié)點
    for (int i=1; i<add; i++)
    {
        temp=temp->next;
    }
    temp->data=newElem;
    return p;
}

四、完整代碼

? ? ? ? 給出的所有代碼的整合代碼:

#include <bits/stdc++.h>
typedef struct line{
    struct line *prior;
    int data;
    struct line *next;
}line;
//雙鏈表的創(chuàng)建
line* initLine(line * head);
//雙鏈表插入元素,add表示插入位置
line * insertLine(line * head,int data,int add);
//雙鏈表刪除指定元素
line * delLine(line * head,int data);
//雙鏈表中查找指定元素
int selectElem(line * head,int elem);
//雙鏈表中更改指定位置節(jié)點中存儲的數(shù)據(jù),add表示更改位置
line *amendElem(line * p,int add,int newElem);
//輸出雙鏈表的實現(xiàn)函數(shù)
void display(line * head);
int main(){
    line *head=NULL;
    //創(chuàng)建雙鏈表
    head=initLine(head);
    display(head);
    //在表中第 3 的位置插入元素 7
    head=insertLine(head,7,3);
    display(head);
    //表中刪除元素 2
    head=delLine(head,2);
    display(head);

    printf("元素 3 的位置是:%d\n",selectElem(head,3));
    //表中第 3 個節(jié)點中的數(shù)據(jù)改為存儲 6
    head=amendElem(head,3,6);
    display(head);
    return 0;
}
line* initLine(line * head){
    head=(line*)malloc(sizeof(line));
    head->prior=NULL;
    head->next=NULL;
    head->data=1;
    line *list=head;
    for(int i=2; i<=5; i++)
    {
        line*body=(line*)malloc(sizeof(line));
        body->prior=NULL;
        body->next=NULL;
        body->data=i;

        list->next=body;
        body->prior=list;
        list=list->next;
    }
    return head;
}
line *insertLine(line *head,int data,int add){
    //新建數(shù)據(jù)域為data的結(jié)點
    line *temp=(line*)malloc(sizeof(line));
    temp->data=data;
    temp->prior=NULL;
    temp->next=NULL;
    //插入到鏈表頭,要特殊考慮
    if(add==1)
    {
        temp->next=head;
        head->prior=temp;
        head=temp;
    }
    else
   	{
        line * body=head;
        //找到要插入位置的前一個結(jié)點
        for(int i=1; i<add-1; i++)
        {
            body=body->next;
        }
        //判斷條件為真,說明插入位置為鏈表尾
        if(body->next==NULL)
        {
            body->next=temp;
            temp->prior=body;
        }
        else
        {
            body->next->prior=temp;
            temp->next=body->next;
            body->next=temp;
            temp->prior=body;
        }
    }
    return head;
}
line *delLine(line *head,int data)
{
    line *temp=head;
    //遍歷鏈表
    while(temp)
    {
        //判斷當(dāng)前結(jié)點中數(shù)據(jù)域和data是否相等,若相等,摘除該結(jié)點
        if(temp->data==data)
        {
            temp->prior->next=temp->next;
            temp->next->prior=temp->prior;
            free(temp);
            return head;
        }
        temp=temp->next;
    }
    printf("鏈表中無該數(shù)據(jù)元素");
    return head;
}
//head為原雙鏈表,elem表示被查找元素
int selectElem(line *head,int elem){
//新建一個指針t,初始化為頭指針 head
    line *t=head;
    int i=1;
    while(t)
    {
        if(t->data==elem)
        {
            return i;
        }
        i++;
        t=t->next;
    }
    //程序執(zhí)行至此處,表示查找失敗
    return -1;
}
//更新函數(shù),其中,add 表示更改結(jié)點在雙鏈表中的位置,newElem 為新數(shù)據(jù)的值
line *amendElem(line *p,int add,int newElem){
    line * temp=p;
    //遍歷到被刪除結(jié)點
    for(int i=1; i<add; i++)
    {
        temp=temp->next;
    }
    temp->data=newElem;
    return p;
}
//輸出鏈表的功能函數(shù)
void display(line *head)
{
    line *temp=head;
    while(temp)
    {
        if(temp->next==NULL)
        {
            printf("%d\n",temp->data);
        }
        else
        {
            printf("%d->",temp->data);
        }
        temp=temp->next;
    }
}

參考文獻:http://c.biancheng.net/view/3343.html

好啦,以上就是本文的全部內(nèi)容啦!創(chuàng)作不易,點個贊再走唄~文章來源地址http://www.zghlxwxcb.cn/news/detail-412430.html

到了這里,關(guān)于雙向鏈表(Double Linked List)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【數(shù)據(jù)結(jié)構(gòu)篇】手寫雙向鏈表、單向鏈表(超詳細)

    【數(shù)據(jù)結(jié)構(gòu)篇】手寫雙向鏈表、單向鏈表(超詳細)

    什么是鏈表 ? 鏈表(Linked List)是用鏈式存儲結(jié)構(gòu)實現(xiàn)的線性表。鏈表示意圖: 鏈表的組成 : 數(shù)據(jù)域 + 引用域 (數(shù)據(jù)域和引用域合稱結(jié)點或元素) 數(shù)據(jù)域存放數(shù)據(jù)元素自身的數(shù)據(jù) 引用域存放相鄰結(jié)點的地址 鏈表的特點 : 鏈表中元素的聯(lián)系依靠引用域 具有線性結(jié)構(gòu)的特

    2024年02月11日
    瀏覽(30)
  • 數(shù)據(jù)結(jié)構(gòu)與算法 | 鏈表(Linked List)

    數(shù)據(jù)結(jié)構(gòu)與算法 | 鏈表(Linked List)

    鏈表(Linked List)是一種線性數(shù)據(jù)結(jié)構(gòu),它由一系列節(jié)點(Node)組成,每個節(jié)點包含兩部分:數(shù)據(jù)和指向下(上)一個節(jié)點的引用(或指針)。鏈表中的節(jié)點按照線性順序連接在一起(相鄰節(jié)點不需要存儲在連續(xù)內(nèi)存位置),不像數(shù)組一樣存儲在連續(xù)的內(nèi)存位置。鏈表通常由

    2024年02月08日
    瀏覽(24)
  • 數(shù)據(jù)結(jié)構(gòu)day06(單向循環(huán)鏈表、雙向鏈表)

    數(shù)據(jù)結(jié)構(gòu)day06(單向循環(huán)鏈表、雙向鏈表)

    雙向鏈表的練習(xí)代碼 head.h fun.c main.c 今日思維導(dǎo)圖哈 ???????

    2024年02月10日
    瀏覽(16)
  • LeetCode 92. Reverse Linked List II【鏈表,頭插法】中等

    LeetCode 92. Reverse Linked List II【鏈表,頭插法】中等

    本文屬于「征服LeetCode」系列文章之一,這一系列正式開始于2021/08/12。由于LeetCode上部分題目有鎖,本系列將至少持續(xù)到刷完所有無鎖題之日為止;由于LeetCode還在不斷地創(chuàng)建新題,本系列的終止日期可能是永遠。在這一系列刷題文章中,我不僅會講解多種解題思路及其優(yōu)化,

    2024年02月09日
    瀏覽(19)
  • 【數(shù)據(jù)結(jié)構(gòu)和算法】使用數(shù)組的結(jié)構(gòu)實現(xiàn)鏈表(單向或雙向)

    【數(shù)據(jù)結(jié)構(gòu)和算法】使用數(shù)組的結(jié)構(gòu)實現(xiàn)鏈表(單向或雙向)

    上文我們通過結(jié)構(gòu)體的結(jié)構(gòu)實現(xiàn)了隊列 、以及循環(huán)隊列的實現(xiàn),我們或許在其他老師的教學(xué)中,只學(xué)到了用結(jié)構(gòu)體的形式來實現(xiàn)鏈表、隊列、棧等數(shù)據(jù)結(jié)構(gòu),本文我想告訴你的是,我們 可以使用數(shù)組的結(jié)構(gòu)實現(xiàn)鏈表、單調(diào)棧、單調(diào)隊列 目錄 前言 一、用數(shù)組結(jié)構(gòu)的好處 1.數(shù)

    2024年01月20日
    瀏覽(96)
  • 【LeetCode 算法】Linked List Cycle II 環(huán)形鏈表 II

    給定一個鏈表的頭節(jié)點 head ,返回鏈表開始入環(huán)的第一個節(jié)點。 如果鏈表無環(huán),則返回 null。 如果鏈表中有某個節(jié)點,可以通過連續(xù)跟蹤 next 指針再次到達,則鏈表中存在環(huán)。 為了表示給定鏈表中的環(huán),評測系統(tǒng)內(nèi)部使用整數(shù) pos 來表示鏈表尾連接到鏈表中的位置(索引從

    2024年02月14日
    瀏覽(19)
  • 【STL源碼分析】c++,List雙向鏈表源碼分析。自己實現(xiàn)list雙向鏈表。

    參考鏈接:https://blog.csdn.net/man_sion/article/details/71003095? 先抽取要實現(xiàn)的功能,由于迭代器有些麻煩,就不使用了。要實現(xiàn)的功能有,push_back,pop_back,insert(指定位置,指定值),insert(指定位置,list,區(qū)間值),reverse,clear,getsize,begin,end,構(gòu)造和析構(gòu)函數(shù),empty。 相關(guān)力扣題目:設(shè)計

    2024年02月03日
    瀏覽(17)
  • 數(shù)據(jù)結(jié)構(gòu)之List(雙向鏈表)的實現(xiàn)

    方法名 參數(shù) 功能 返回 find const T val, int n, listNode * p 區(qū)間查找 從p往前數(shù)n個節(jié)點 指針或NULL const T val, listNode * p 區(qū)間查找 從p往前到首節(jié)點 const T val 查找 Size void 鏈表規(guī)模 size empty void 判空 bool first void 返回首節(jié)點 首節(jié)點指針 clear void 清空鏈表 void insertAsFirst const T val 作為首節(jié)

    2024年02月16日
    瀏覽(25)
  • 算法競賽基礎(chǔ):C++雙向鏈表的結(jié)構(gòu)和實現(xiàn)(普通鏈表、List、靜態(tài)鏈表)

    本文將會介紹在算法競賽中雙向鏈表的幾種使用方式,適合有一定基礎(chǔ)的人閱讀。 一般來說,普通的鏈表結(jié)構(gòu)是這樣的: next指針指向下一個鏈表,這樣的結(jié)構(gòu)只能夠支持單向查詢。 雙向鏈表,顧名思義,就是可以支持雙向的訪問和查詢。 也就是這樣的: 這種鏈表為訪問前

    2024年01月24日
    瀏覽(12)
  • Linked List Mock

    203. Remove Linked List Elements Solved Easy Topics Companies Given the? head ?of a linked list and an integer? val , remove all the nodes of the linked list that has? Node.val == val , and return? the new head . 206. Reverse Linked List Solved Easy Topics Companies Given the? head ?of a singly linked list, reverse the list, and return? the reversed

    2024年04月12日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包