日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢(xún)客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

一:鏈表是什么

 

1、鏈表是物理存儲(chǔ)單元上非連續(xù)的、非順序的存儲(chǔ)結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過(guò)鏈表的指針地址實(shí)現(xiàn),有一系列結(jié)點(diǎn)(地址)組成,結(jié)點(diǎn)可動(dòng)態(tài)的生成。

 

2、結(jié)點(diǎn)包括兩個(gè)部分:(1)存儲(chǔ)數(shù)據(jù)元素的數(shù)據(jù)域(內(nèi)存空間),(2)存儲(chǔ)指向下一個(gè)結(jié)點(diǎn)地址的指針域。

 

3、相對(duì)于線性表順序結(jié)構(gòu),操作復(fù)雜。

 

4.鏈表分為 (1)單鏈表 (2)雙鏈表 (3)單向循環(huán)鏈表 (4)雙向循環(huán)鏈表

 

二:鏈表的作用

 

1、實(shí)現(xiàn)數(shù)據(jù)元素的存儲(chǔ)按一定順序儲(chǔ)存,允許在任意位置插入和刪除結(jié)點(diǎn)。

 

2、包括單向結(jié)點(diǎn),雙向結(jié)點(diǎn),循環(huán)接點(diǎn)

 

三:鏈表與數(shù)組的區(qū)別

說(shuō)到鏈表那肯定要聊一下數(shù)組,為什么會(huì)出現(xiàn)鏈表呢?

 

(1)數(shù)組:使用一塊連續(xù)的內(nèi)存空間地址去存放數(shù)據(jù),但

 

例如:

int  a[5]={1,2,3,4,5}。突然我想繼續(xù)加兩個(gè)數(shù)據(jù)進(jìn)去,但是已經(jīng)定義好的數(shù)組不能往后加,只能通過(guò)定義新的數(shù)組

 

int b[7]={1,2,3,4,5,6,7};      ***********這樣就相當(dāng)不方便比較浪費(fèi)內(nèi)存資源,對(duì)數(shù)據(jù)的增刪不好操作。

 

(2)鏈表:使用多個(gè)不連續(xù)的內(nèi)存空間去存儲(chǔ)數(shù)據(jù), 可以 節(jié)省內(nèi)存資源(只有需要存儲(chǔ)數(shù)據(jù)時(shí),才去劃分新的空間),對(duì)數(shù)據(jù)的增刪比較方便。

 

四、鏈表的優(yōu)缺

優(yōu)點(diǎn):

(1)插入和刪除速度快,保留原有的物理順序,在插入或者刪除一個(gè)元素的時(shí)候,只需要改變指針指向即可。(2)沒(méi)有空間限制,存儲(chǔ)元素?zé)o上限,只與內(nèi)存空間大小有關(guān)。(3)動(dòng)態(tài)分配內(nèi)存空間,不用事先開(kāi)辟內(nèi)存

 

缺點(diǎn):

(1)占用額外的空間以存儲(chǔ)指針,比較浪費(fèi)空間,不連續(xù)存儲(chǔ),malloc函數(shù)開(kāi)辟空間碎片比較多) (2) 查找速度比較慢,因?yàn)樵诓檎視r(shí),只能順序查找,需要循環(huán)鏈表

 

五、關(guān)于頭指針,頭節(jié)點(diǎn),首元節(jié)點(diǎn)的那些事

頭指針:指向鏈表第一個(gè)節(jié)點(diǎn)的指針(不一定是頭節(jié)點(diǎn),因?yàn)?hellip;…鏈表要是沒(méi)有頭節(jié)點(diǎn)呢?),沒(méi)有實(shí)際開(kāi)辟空間 (即沒(méi)有用malloc等動(dòng)態(tài)分配內(nèi)存) 而且必須存在,因?yàn)轭^指針不存在,就不便于對(duì)鏈表進(jìn)行操作。

 

頭節(jié)點(diǎn):不是必須存在(若存在則為鏈表的第一個(gè)節(jié)點(diǎn))其主要作用是使所有鏈表(包括空表)的頭指針?lè)强眨⑹箤?duì)單鏈表的插入、刪除操作不需要區(qū)分是否為空表或是否在第一個(gè)位置進(jìn)行(還是挺有用的)。其數(shù)據(jù)域可以不儲(chǔ)存任何數(shù)據(jù),若儲(chǔ)存則通常是鏈表的長(zhǎng)度啥的。

 

首元節(jié)點(diǎn):第一個(gè)數(shù)據(jù)域中儲(chǔ)存有效數(shù)據(jù)的節(jié)點(diǎn) 若頭節(jié)點(diǎn)不存在 則其為鏈表的第一個(gè)節(jié)點(diǎn),是一定要存在的(除非是空表)

 

有關(guān)鏈表的一些操作

1.單鏈表 

節(jié)點(diǎn)結(jié)構(gòu)默認(rèn)為:

 

struct ListNode

{

int val;

struct ListNode *next;

}

 

①單鏈表的創(chuàng)建

//創(chuàng)建鏈表 

struct ListNode* createList()

{

    struct ListNode*p=NULL,*tail=NULL,*head=NULL;//p為待開(kāi)辟的節(jié)點(diǎn)指針,tail為指向鏈表尾部的指針,head為指向鏈表頭部的指針。

                                  //筆者喜歡在創(chuàng)建鏈表時(shí) 創(chuàng)建head tail 兩個(gè)指針 雖然不一定都用得到

    int num;                        //將指針置空是個(gè)好習(xí)慣 

    scanf("%d",&num);

    //尾插法  順序插法 

    while(num!=-1)//假設(shè)以num/val值為-1作為鏈表的結(jié)束標(biāo)志  或者你用定長(zhǎng)條件也行 

    {

       p=(struct ListNode*)malloc(sizeof(struct ListNode));//注意此處用sizeof計(jì)算大小時(shí)在ListNode前要加struct關(guān)鍵字

       p->val=num;

       p->next=NULL;

       if(head==NULL)//第一次循環(huán)時(shí)將頭指針head指向p 

       {

           head=p;    

       } 

       else

       {

          tail->next=p;    

       } 

       tail=p;//此句放else里面也行  筆者更喜歡在第一次循環(huán)時(shí)就將tail與p與head產(chǎn)生關(guān)聯(lián) 

       scanf("%d",&num); 

    } 

//    頭插法   逆序插法 

//    while(num!=-1)

//    {

//        p=(struct ListNode*)malloc(sizeof(struct ListNode));

//        p->val=num;

//        if(head==NULL)

//        {

//            head=p;

//        }

//        else

//        {

//           p->next=head;

//           head=p;    

//        }

//    } 

    tail->next=NULL//用p->next也行 這是尾插法 

    return head;//返回鏈表頭指針                              

②鏈表節(jié)點(diǎn)的插入

 

struct ListNode *insertList(ListNode *head,int index,int num)//index 表示在鏈表中插入的位置(從1開(kāi)始)原位置的元素接在其后  num表示要插入的數(shù)值

{

    struct ListNode *p=NULL,q;//在此q為虛擬節(jié)點(diǎn) 主要方便對(duì)鏈表進(jìn)行操作 

    int cnt=1;//計(jì)數(shù)器從1開(kāi)始計(jì)數(shù)

    if(head==NULL&&head->next==NULL)//鏈表為空 返回一個(gè)空指針 

    return NULL; 

    if(index==1)//若插在頭結(jié)點(diǎn)(在此特指鏈表的第一個(gè)節(jié)點(diǎn))的位置

    {

        p=(struct ListNode*)malloc(sizeof(struct ListNode));//給p開(kāi)辟實(shí)際空間 用來(lái)儲(chǔ)存操作存入的值 

        p->val=num;

        p->next=head; 

        head=p; 

    } 

    else 

    {

        q=head;

        while(q->next!=NULL&&cnt<=index)//對(duì)于鏈表我們通常對(duì)當(dāng)前節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)進(jìn)行操作 

        {

            if(cnt+1<index)//為什么要加一呢?因?yàn)楸硎鞠乱粋€(gè)位置 

            {

                q=q->next; 

            }

            else

            {

                p=(struct ListNode *)malloc(sizeof(struct ListNode));

                p->val=num;

                p->next=q->next;

                q->next=q;    

            }

        }

    }

    if(cnt<index)//如果cnt還是 小于 index 則表明插在鏈表末尾 

    {

        p=(struct ListNode*)malloc(sizeof(struct ListNode));

        p->val=num;

        p->next=NULL;

        q->next=p;

    } 

    return head;

}   

 

③鏈表節(jié)點(diǎn)的刪除

 

struct ListNode *deleteList(struct ListNode *head,int num)//執(zhí)行刪除節(jié)點(diǎn)val值為num的操作

{

    struct ListNode *p=NULL,*q=NULL;//p,q均為輔助指針 不給他們開(kāi)辟實(shí)際空間 

    if(head->val==num)//若刪除節(jié)點(diǎn)為頭結(jié)點(diǎn) 

    {

           p=head;

           head=head->next;

           free(p);

    } 

    else//若刪除節(jié)點(diǎn)為除頭結(jié)點(diǎn)外的其他節(jié)點(diǎn) 

    {

        p=head;

        while(p->next!=NULL)

        {

            if(p->next->val==num)

            {

                q=p->next;

                p->next=p->next->next;

                free(q);    

            } 

            else

            {

                p=p->next;

            }

        }

    }

    return head; 

     

鏈表的遍歷

 

void printList(struct ListNode *head)

{

    struct ListNode *p=head;//p依然為輔助指針

    while(p!=NULL)//因?yàn)槭潜闅v(打印輸出)操作 所以對(duì)當(dāng)前節(jié)點(diǎn)進(jìn)行操作即可 

    {

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

       p=p->next; 

    } 

}

 

雙向鏈表

雙向鏈表即單鏈表由單向的鏈變成了雙向的鏈(一個(gè)指針域(next)變成一前一后兩個(gè)指針域(prev,next)) 這里只演示雙向鏈表的創(chuàng)建

另:

節(jié)點(diǎn)結(jié)構(gòu)為:

 

struct ListNode

{

int val;

ListNode *prev;

ListNode *next;

};

 

雙向鏈表的創(chuàng)建 

struct ListNode *createDbList()

{

    struct ListNode*p=NULL,*head=NULL,*tail=NULL;

    int num;

    scanf("%d",&num);

    while(num!=-1)//以-1作為創(chuàng)建鏈表結(jié)束的標(biāo)志 

    {

        p=(struct ListNode*)malloc(sizeof(struct ListNode));

        p->val=num;

        if(head==NULL)//這里主要演示尾插法 

        {

           head=p;    

           p->prev=NULL; //就不將雙向鏈表和循環(huán)鏈表相互摻和了 

        } 

        else

        {

          tail->next=p;

          p->prev=tail;     

        }

        tail=p;

    } 

    tail->next=NULL;

}

 

循環(huán)鏈表

即將鏈表首尾相接 同樣這里只演示循環(huán)鏈表的創(chuàng)建

 

struct ListNode *createList()

{

    struct ListNode*p,*head,*tail;

    int num;

    scanf("%d",&num);

    while(num!=-1)

    {

       p=(struct ListNode*)malloc(sizeof(struct ListNode));

       p->val=num;

       if(head==NULL)

       {

          head=p;    

       }    

       else

       {

             tail->next=p;

       }

       tail=p;

    }

    tail->next=head;//創(chuàng)建結(jié)束后將鏈表首尾相接    

 

靜態(tài)鏈表

靜態(tài)鏈表的節(jié)點(diǎn)通常用結(jié)構(gòu)體數(shù)組表示

 

struct  staticListNode

   int val;

   int cur;//游標(biāo)cur用來(lái)儲(chǔ)存后繼節(jié)點(diǎn)的下標(biāo)

};

 

 

1.Floyd判圈法:判斷鏈表是否有環(huán)(快慢指針的應(yīng)用)

 

 

對(duì)于鏈表找環(huán)路的問(wèn)題,有一個(gè)通用的解法——快慢指針(Floyd) 。給定兩個(gè)指針, 分別命名為 slow 和 fast ,起始位置在鏈表的開(kāi)頭。每次 fast 前進(jìn)兩步, slow 前進(jìn)一步。如果 fast 可以走到盡頭,那么說(shuō)明沒(méi)有環(huán)路;如果fast 可以無(wú)限走下去,那么說(shuō)明一定有環(huán)路,且一定存 在一個(gè)時(shí)刻 slow 和 fast 相遇。當(dāng) slow 和 fast 第一次相遇時(shí),我們將 fast 重新移動(dòng)到鏈表開(kāi)頭,并 讓 slow 和 fast 每次都前進(jìn)一步。當(dāng) slow 和 fast 第二次相遇時(shí),相遇的節(jié)點(diǎn)即為環(huán)路的開(kāi)始點(diǎn)。

 

2. 判斷兩個(gè)鏈表是否相交

 

 

假設(shè)鏈表 A 的頭節(jié)點(diǎn)到相交點(diǎn)的距離是 a,鏈表 B 的頭節(jié)點(diǎn)到相交點(diǎn)的距離是 b,相交點(diǎn)到鏈表終點(diǎn)的距離為 c。我們使用兩個(gè)指針,分別指向兩個(gè)鏈表的頭節(jié)點(diǎn),并以相同的速度前進(jìn),若到達(dá)鏈表結(jié)尾,則移動(dòng)到另一條鏈表的頭節(jié)點(diǎn)繼續(xù)前進(jìn)。按照這種前進(jìn)方法,兩個(gè)指針會(huì)在a + b + c 次前進(jìn)后同時(shí)到達(dá)相交節(jié)點(diǎn)

————————————————

版權(quán)聲明:本文為CSDN博主「legendarykk」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.NET/legendarykk/article/details/125592024

分享到:
標(biāo)簽:鏈表
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定