C語(yǔ)言鏈表學(xué)習(xí)筆記_P794

寫(xiě)在前面:

  • 1.首先鏈表的本質(zhì)只是一種特殊的結(jié)構(gòu)體,所以C語(yǔ)言當(dāng)作并沒(méi)有現(xiàn)成的函數(shù)去幫助你延長(zhǎng)鏈表或者幫助你輸出鏈表,所有的東西全部需要靠你自己.
  • 2.學(xué)習(xí)鏈表之前需要的預(yù)備知識(shí):結(jié)構(gòu)體,指針,動(dòng)態(tài)內(nèi)存分配.
    P.S.鏈表本身并不需要?jiǎng)討B(tài)內(nèi)存分配,但是可以確保你在函數(shù)中生成的鏈表所占用的內(nèi)存不會(huì)在函數(shù)結(jié)束后被釋放.
    PP.SS.如果你看不懂上面那句話(huà),不明白我在說(shuō)什么可以學(xué)習(xí)一下C語(yǔ)言中變量的生存周期和動(dòng)態(tài)內(nèi)存分配.

1.什么是鏈表

在之前已經(jīng)說(shuō)過(guò)鏈表不過(guò)是定義特殊的結(jié)構(gòu)體
先來(lái)在邏輯上理解一下鏈表
這里借用一下另一個(gè)blog的圖片:https://blog.csdn.net/morixinguan/article/details/68951912

image

鏈表這種結(jié)構(gòu)體的特殊之處在于有一個(gè)*next.
*next為一個(gè)指向這種結(jié)構(gòu)體的下一個(gè)節(jié)點(diǎn)的指針,這種結(jié)構(gòu)體中均有一個(gè)*next
當(dāng)你訪(fǎng)問(wèn)首位鏈表時(shí)*next中存放了鏈表中的下一個(gè)節(jié)點(diǎn)的地址如此將本互不相連的若干個(gè)結(jié)構(gòu)體連接了起來(lái),同時(shí)這些結(jié)構(gòu)體數(shù)據(jù)類(lèi)型又相同如此起到了一種類(lèi)似于數(shù)組卻比數(shù)組更加方便的數(shù)據(jù)類(lèi)型,被稱(chēng)為鏈表.
這條鏈從Head開(kāi)始(即鏈表第一個(gè)節(jié)點(diǎn)的地址)最后一個(gè)節(jié)點(diǎn)依然有*next不過(guò)它的值等于NULL.

2.如何定義一個(gè)鏈表

如下是一個(gè)鏈表的定義.

struct student {
    int num,score;//這就是我們所說(shuō)的數(shù)據(jù)域
    struct student *next;
};//定義一個(gè)結(jié)構(gòu)體(鏈表) 

數(shù)據(jù)的多少名稱(chēng)大小都可以自己定義.

3.如何使用

定義好了鏈表接下來(lái)便是如何使用它
這里我便以例代講:


題目
#include<stdio.h>
#include<malloc.h>

/* User Code Begin(考生可在本行后添加代碼,定義程序中使用的結(jié)構(gòu)體類(lèi)型、聲明自定義函數(shù)的原型,行數(shù)不限) */

struct student {
    int num,score;
    struct student *next;
};//定義一個(gè)結(jié)構(gòu)體(鏈表) 

struct student *creat(void);
struct student *merge(struct student*a,struct student*b);
/* User Code End(考生添加代碼結(jié)束) */

/* print以規(guī)定的格式完成遍歷顯示指定的鏈表 */
void print(char *Info, struct student *Head);

int main(void)
{   
    struct student *ah, *bh;
    
    printf("創(chuàng)建鏈表A,請(qǐng)輸入學(xué)號(hào)及成績(jī)(均輸入為0時(shí)表示停止):\n");
    ah = creat();
    printf("\n創(chuàng)建鏈表B,請(qǐng)輸入學(xué)號(hào)及成績(jī)(均輸入為0時(shí)表示停止):\n");
    bh = creat();

    print("\n鏈表A:", ah);
    print("\n鏈表B:", bh);
    
    ah = merge(ah, bh);
    print("\n鏈表A、B合并后:", ah);
    
    return 0;
}

void print(char *Info, struct student *Head)
{
    printf("%s", Info);
    while (Head != NULL)
    {
        printf("%d,%d  ", Head->num, Head->score);
        Head = Head->next;
    }
}

/* User Code Begin(考生在此后完成自定義函數(shù)的設(shè)計(jì),行數(shù)不限) */
struct student *creat(void)//定義函數(shù)建立鏈表
{
    struct student *Head,*p1,*p2;//*Head是這個(gè)鏈表的首地址單獨(dú)定義并且保存下來(lái)
    int n=1;
    Head=p1=p2=(struct student*)malloc(sizeof(struct student));
    while(1)
    {
        printf("學(xué)生 %d: ",n);
        scanf("%d %d",&(p2->num),&(p2->score));
//通過(guò)p2保存輸入的數(shù)據(jù)
        if(p2->num==0 && p2->score==0)
//普判斷是否要結(jié)束輸入
        {
            if(n==1)
            {
                return NULL;//如果沒(méi)有輸入任何數(shù)據(jù)就直接要求結(jié)束輸入就返回NULL
            }
            return Head;//否則返回鏈表首地址
        }
        if(Head==NULL)//判斷是否是第一位鏈表
        {
            //如果是鏈表的第一位的話(huà)執(zhí)行如下操作
            Head=p2;//做為Head保存下來(lái)
            p1=p2;//同時(shí)賦值給p1方便修改next
            p2= (struct student *)malloc(sizeof(struct student));//為p2分配新地址
        }
        else
        {
            //如果不是第一位的話(huà):
            p1->next=p2;//為p1中next賦值為p2
            p2->next=NULL;//將p2中next定義為null
            p1=p2;//將p2的地址賦值給p1
            p2= (struct student *)malloc(sizeof(struct student));
            //為p2分配新的地址
        }
        n++;    
    }
}

struct student *merge(struct student *a,struct student *b)//定義函數(shù)合并兩個(gè)鏈表
{
    struct student *HEAD=a;
    struct student *mid=NULL;
    while(1)
    {
        if(a==NULL)
        {
            HEAD=b;
            return HEAD;
        }
        if(a->next==NULL)
        {
            a->next=b;
            return HEAD;
        }
        else
        {
            a=a->next;
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容