日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

线性表(二)——链表

發(fā)布時(shí)間:2025/3/21 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线性表(二)——链表 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 鏈表(Linked Table)
    • 1.單鏈表(singly linked list)
      • 元素的構(gòu)成
      • 鏈表的基本操作
        • 鏈表的創(chuàng)建
        • 遍歷操作
        • 查找操作
        • 插入操作
        • 刪除操作

鏈表(Linked Table)

線性表的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)生成的表,稱作“鏈表”。

鏈表分為單向鏈表和雙向鏈表。

1.單鏈表(singly linked list)

單鏈表(singly linked list)是用一組任意的存儲(chǔ)單元存放的線性表元素,這組存儲(chǔ)單元可以連續(xù)也可以不連續(xù),甚至可以零散分布在內(nèi)存中的任意位置。為了能夠體現(xiàn)出數(shù)據(jù)元素之間的邏輯關(guān)系,每個(gè)存儲(chǔ)單元在在存儲(chǔ)數(shù)據(jù)元素的同時(shí),還必須存儲(chǔ)其后繼元素所在的地址信息,這個(gè)地址信息稱為指針,這兩部分組成了數(shù)據(jù)元素的存儲(chǔ)映像,稱為結(jié)點(diǎn)(node)。

鏈表的簡(jiǎn)單原理圖如圖:

結(jié)點(diǎn)結(jié)構(gòu)如圖所示:

元素的構(gòu)成

每個(gè)元素本身由兩部分組成:

  • data 稱為“數(shù)據(jù)域”,用來(lái)存放數(shù)據(jù)元素(可以是一個(gè)成員,或多個(gè)成員);
  • next 稱為“指針域”,用來(lái)存放該結(jié)點(diǎn)的后繼結(jié)點(diǎn)的地址。
  • 單鏈表正是通過每個(gè)結(jié)點(diǎn)的指針域?qū)⒕€性表的數(shù)據(jù)元素按其邏輯次序鏈接在一起,由于每個(gè)結(jié)點(diǎn)只有一個(gè)指針域,故稱為單鏈表。

    單鏈表中每個(gè)結(jié)點(diǎn)的存儲(chǔ)地址存放在其前驅(qū)結(jié)點(diǎn)的next域中,而第一個(gè)元素?zé)o前驅(qū),所以設(shè)頭指針(head pointer)指向第一個(gè)元素所在結(jié)點(diǎn)(稱為開始結(jié)點(diǎn)),整個(gè)單鏈表的存取必須從頭指針開始進(jìn)行,因而頭指針具有標(biāo)識(shí)一個(gè)單鏈表的作用;同時(shí),由于最后一個(gè)元素?zé)o后繼,故最后一個(gè)元素所在結(jié)點(diǎn)(稱為終端結(jié)點(diǎn))的指針域?yàn)榭?#xff0c;即NULL。

    指向第一個(gè)結(jié)點(diǎn)(開始結(jié)點(diǎn))的指針必須保存,否則該鏈表將會(huì)消失。通常在單鏈表的開始結(jié)點(diǎn)之前附設(shè)一個(gè)類型相同的結(jié)點(diǎn),稱為頭結(jié)點(diǎn)(head node)。加上頭結(jié)點(diǎn)之后,無(wú)論單鏈表是否為空,頭指針始終指向頭結(jié)點(diǎn)。

    鏈表結(jié)點(diǎn)中包含一個(gè)指針變量,用于存放下一個(gè)Node結(jié)構(gòu)結(jié)點(diǎn)的地址,所以該指針必須是與結(jié)構(gòu)體相同的數(shù)據(jù)類型。

    typedef int ElementType; struct Node {ElementType data; //ElementType是date的數(shù)據(jù)類型struct Node *Next; //指向直接后繼元素的指針 };

    鏈表的基本操作

    在構(gòu)建鏈表時(shí),需要逐個(gè)創(chuàng)建結(jié)點(diǎn),并且把生成的每個(gè)結(jié)點(diǎn)加入到鏈表中。創(chuàng)建結(jié)點(diǎn)包括3個(gè)步驟:

  • 為結(jié)點(diǎn)分配內(nèi)存單元;
  • 把數(shù)據(jù)存儲(chǔ)到結(jié)點(diǎn)中;
  • 把結(jié)點(diǎn)插入到鏈表中。
  • 鏈表的創(chuàng)建

    創(chuàng)建一個(gè)僅含頭結(jié)點(diǎn)的空鏈表:

    typedef struct Node *List; int iCount = 0; //記錄鏈表長(zhǎng)度的全局變量 List InitList() {struct Node *pHead = (struct Node*)malloc(sizeof(struct Node)); //為頭結(jié)點(diǎn)分配內(nèi)存空間pHead->Next = NULL;iCount = 0;return pHead; }

    鏈表還可以使用頭指針創(chuàng)建

    List InitList() {List pHead = NULL; //頭指針為空return pHead; }

    遍歷操作

    遍歷打印鏈表元素

    void PrintList(List L) {List p = L->Next; //工作指針p初始化while(p != NULL){printf("%d\n",p->data);p = p->Next;} }

    求線性表長(zhǎng)度

    int Length(List L) {List p = L->Next; //工作指針p初始化int count = 0; //累加器count初始化while(p != NULL){p = p->Next;count++;}return count; }

    查找操作

    按位查找:從頭結(jié)點(diǎn)出發(fā)順Next域逐個(gè)結(jié)點(diǎn)向下搜索,當(dāng)工作指針p指向某個(gè)結(jié)點(diǎn)時(shí)判斷是否為第 i 個(gè)結(jié)點(diǎn),若是,則查找成功;否則,將工作指針后移。對(duì)每個(gè)結(jié)點(diǎn)依次執(zhí)行上述操作,知道p為NULL時(shí)查找失敗。

    ElementType GetData(List L, int i) {List p = L->Next; //工作指針p初始化,指向頭結(jié)點(diǎn)后的第一個(gè)元素int count = 1; //累加器count初始化while(p != NULL && count < i){p = p->Next;count++;}if(p == NULL) {printf("The input position exceeds the length of the linked list");}elsereturn p->data; }

    按值查找:對(duì)鏈表中的元素依次進(jìn)行比較,如果查找成功,返回元素的序號(hào),如果查找不成功,則返回0表示查找失敗。

    int Locate(List L, ElementType element) {List p = L->Next; //工作指針p初始化,指向頭結(jié)點(diǎn)后的第一個(gè)元素int count = 1; //累加器count初始化while(p != NULL){if(p->data == element)return count; //查找成功,結(jié)束函數(shù)并返回序號(hào)p = p->Next;count++;}return 0; //表示查找失敗,返回0 }

    插入操作

    每次加入一個(gè)結(jié)點(diǎn),使用循環(huán)可創(chuàng)建一個(gè)含有n個(gè)結(jié)點(diǎn)的單鏈表

    頭插法:

    頭插法是每次將新申請(qǐng)的結(jié)點(diǎn)插在頭結(jié)點(diǎn)的后面,其執(zhí)行過程如圖所示。

    void ListHeadInsert(List L) {char c;List pHead = L;char flag;List pNew;do{iCount++;pNew = (struct Node *)malloc(sizeof(struct Node));printf("Please enter the Number\n");scanf("%d",&pNew->data);pNew->Next = pHead->Next; //新結(jié)點(diǎn)的指針指向頭結(jié)點(diǎn)原指向的位置pHead->Next = pNew; //頭結(jié)點(diǎn)指針指向新結(jié)點(diǎn)printf("Do you want to continue typing?(y/n)\n");while((c = getchar()) != '\n' && c != EOF);//不停地使用getchar()獲取緩沖中字符,直到獲取的c是“\n”或文件結(jié)尾符EOF為止scanf("%c",&flag);}while('y' == flag); }

    尾插法:

    尾插法就是每次將新申請(qǐng)的結(jié)點(diǎn)插在終端結(jié)點(diǎn)的后面,其執(zhí)行過程如圖所示。

    void ListEndInsert(List L) {char c;List pHead = L;char flag;List pNew, pEnd;pEnd = pHead; //尾指針初始化,指向頭結(jié)點(diǎn)do{iCount++;pNew = (struct Node *)malloc(sizeof(struct Node));printf("Please enter the Number\n");scanf("%d",&pNew->data);pEnd->Next = pNew; //尾指針指向新結(jié)點(diǎn)pEnd = pNew; //pEnd指向新結(jié)點(diǎn)printf("Do you want to continue typing?(y/n)\n");while((c = getchar()) != '\n' && c != EOF);//不停地使用getchar()獲取緩沖中字符,直到獲取的c是“\n”或文件結(jié)尾符EOF為止scanf("%c",&flag);}while('y' == flag);pEnd->Next = NULL; }

    和前面的創(chuàng)建初始化寫在一起可以創(chuàng)建一個(gè)含N個(gè)元素的鏈表。

    向鏈表中任意位置插入結(jié)點(diǎn),插入到第 i 個(gè)位置,即插入到鏈表 i-1 與 i 之間。必須先掃描鏈表找到 i-1 的存儲(chǔ)地址 p ,然后生成一個(gè)新的結(jié)點(diǎn) pNew,將 pNew 的Next域指向第 i 個(gè)結(jié)點(diǎn),將結(jié)點(diǎn) p 的Next域指向新結(jié)點(diǎn)。

    void Insert(List L, int i, ElementType element) {List pNew;List p = L; //工作指針p初始化,指向頭結(jié)點(diǎn)int count = 0; //累加器count初始化while(p != NULL && count < i-1) //查找第 i-1 個(gè)結(jié)點(diǎn){p = p->Next; //工作指針后移count++;}if(p == NULL) {printf("The input position exceeds the length of the linked list");}else{pNew = (struct Node *)malloc(sizeof(struct Node));pNew->data = element;pNew->Next = p->Next;p->Next = pNew; //將新結(jié)點(diǎn)插入到結(jié)點(diǎn)p之后iCount++; //鏈表長(zhǎng)度加1} }

    刪除操作

    將單鏈表的第 i 個(gè)結(jié)點(diǎn)刪去,首先要找到 i-1 個(gè)結(jié)點(diǎn)的存儲(chǔ)地址p,然后令p的Next域指向 i 的后繼結(jié)點(diǎn),釋放結(jié)點(diǎn) i 的存儲(chǔ)空間。被刪結(jié)點(diǎn)的的前驅(qū)結(jié)點(diǎn)p存在且不是終端結(jié)點(diǎn)時(shí),才能確定被刪結(jié)點(diǎn)存在。

    void Delete(List L, int i) {List pTemp;List p = L; //工作指針p初始化,指向頭結(jié)點(diǎn)int count = 0; //累加器count初始化while(p != NULL && count < i-1) //查找第 i-1 個(gè)結(jié)點(diǎn){p = p->Next; //工作指針后移count++;}if(p == NULL || p->Next == NULL) {printf("The input position exceeds the length of the linked list");}else{pTemp = p->Next; //暫存被刪結(jié)點(diǎn)p->Next = pTemp->Next; //摘鏈free(pTemp);iCount--; //鏈表長(zhǎng)度減1} }

    刪除整個(gè)鏈表

    void DeleteList(List L) {List p, pTemp;p = L->Next;L->Next = NULL;while(p != NULL){pTemp = p->Next;free(p);p = pTemp;iCount--;} }

    總結(jié)

    以上是生活随笔為你收集整理的线性表(二)——链表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。