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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【数据结构基础笔记】【链表】

發(fā)布時間:2023/12/1 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【数据结构基础笔记】【链表】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

代碼參考《妙趣橫生的算法.C語言實現(xiàn)》

文章目錄

  • 前言
    • 1、鏈表基礎(chǔ)
    • 2、創(chuàng)建一個鏈表
    • 3、插入結(jié)點
    • 4、刪除結(jié)點
    • 5、銷毀鏈表
    • 6、實例分析


前言

本章總結(jié):鏈表的定義、創(chuàng)建、銷毀,結(jié)點的插入與刪除


1、鏈表基礎(chǔ)

鏈表的物理存儲結(jié)構(gòu)是用一組地址任意的存儲單元存儲數(shù)據(jù)的。
在鏈表結(jié)構(gòu)中,每個數(shù)據(jù)元素記錄都存放在鏈表的一個結(jié)點node中,而每個結(jié)點之間由指針將其連接到一起。
每個結(jié)點由指針域(存放后繼結(jié)點的位置)、數(shù)據(jù)域構(gòu)成。
一個鏈表通常有一個表頭,是一個指針變量,用來存放第一個結(jié)點地址。
鏈表的最后一個結(jié)點的的指針域要置空,表示為鏈表的尾結(jié)點。

鏈表特點:
1、每個結(jié)點包括兩個部分:數(shù)據(jù)域和指針域
數(shù)據(jù)域用來存放數(shù)據(jù)元素本身信息,指針域用來存放后繼結(jié)點的地址
2、鏈表邏輯上是連續(xù)的,但物理上不一定是連續(xù)存儲結(jié)點。
3、只要獲取鏈表的頭結(jié)點,就可以通過指針遍歷整條鏈表
一個鏈表結(jié)點可以描述為:

typedef struct node{ElemType data; //數(shù)據(jù)域struct node *next; //指針域 }LNode,*LinkList;

每個結(jié)點的類型是LNode
*LinkList是指向LNode類型數(shù)據(jù)的指針類型定義。
所以 LNode *L 與 LinkList L; 是等價的。

2、創(chuàng)建一個鏈表

LinkList GreatLinkList(int n) {//建立一個長度為n的鏈表LinkList p,r,list=NULL; //p:相當(dāng)于每次新建結(jié)點的暫存器,r:相當(dāng)于插入結(jié)點的上一個結(jié)點,永遠(yuǎn)指向原先鏈表的最后一個結(jié)點。list鏈表的頭指針ElemType elem; //獲取暫存數(shù)據(jù)int i; //定義累加器for(i=0;i<n;i++){scanf("%d",&elem);p=(LinkList)malloc(sizeof(LNode)); //分配內(nèi)存,并將首地址送到pp->data=elem; //置入數(shù)據(jù)p->next =NULL; //指針指向NULL,暫時不考慮下一個結(jié)點if(!list) //如果鏈表為空,則新創(chuàng)建的結(jié)點就是該鏈表的第一個結(jié)點list=p;else //如果鏈表不為空,則將新建立的結(jié)點連接到之前鏈表的尾部r->next=p;r=p; //將p結(jié)點的數(shù)據(jù)賦給r}return list; //將鏈表的頭指針返回主調(diào)函數(shù),通過list就可以訪問鏈表中的每個結(jié)點,并進(jìn)行操作 }

3、插入結(jié)點

步驟描述:
1、創(chuàng)建新節(jié)點,用指針p指向該結(jié)點
2、將q指向結(jié)點的next域的值賦值給p指向結(jié)點的next域
3、將p的值賦值給q的next域

代碼描述:

void insertList(LinkList *list,LinkList q,ElemType e) {//向鏈表中由指針q指向的結(jié)點后面插入結(jié)點,結(jié)點數(shù)據(jù)位eLinkList p;p=(LinkList)malloc(sizeof(LNode)); //生成一個新節(jié)點,由p指向它p->data=e;if(!*list) //如果鏈表為空{*list=p;p->next=NULL;} //當(dāng)鏈表為空的時候,q沒有意義,只能在頭結(jié)點后面插入第一個元素else{//當(dāng)鏈表不為空的時候,認(rèn)為q指向的結(jié)點一定存在//將q指向的結(jié)點的next域的值賦給p指向的結(jié)點的next域p->next=q->next;q->next=p; } }

通過這個算法同樣可以創(chuàng)建一個鏈表,因為鏈表為空時,list==NULL,可以自動創(chuàng)建一個結(jié)點。在下面創(chuàng)建其他結(jié)點時,只要始終將指針q指向鏈表的最后一個結(jié)點,就可以創(chuàng)建出一個鏈表

4、刪除結(jié)點

從非空鏈表中刪除q所指的結(jié)點。
考慮三個情況:1、q指向的是鏈表的第一個結(jié)點
2、q指向的結(jié)點的前驅(qū)結(jié)點的指針已知
3、q指向的結(jié)點的前驅(qū)結(jié)點的指針未知
步驟:
1:將q所指的結(jié)點的指針域next的值賦給頭指針list,讓list指向第二個結(jié)點,再釋放掉q所指的結(jié)點即可。
2:假設(shè)前驅(qū)指針為r,將q所指的結(jié)點的指針域next的值賦給r的指針域next,釋放掉q所指結(jié)點
3:當(dāng)q所指的結(jié)點的前驅(qū)結(jié)點的指針未知,需要通過鏈表頭指針list遍歷鏈表,找到q的前驅(qū)結(jié)點,并將該指針賦值給變量r,再按照第二種情況去做即可

情況1、2的代碼描述:

void delLink(LinkList *list,LinkList r,LinkList q) {if(q==*list) //情況1:q指向鏈表的第一個結(jié)點*list=q->next;else //情況2:q指向的結(jié)點前驅(qū)結(jié)點的指針已知r->next=q->next;free(q); }

情況1、3的代碼描述:

void delLink(LinkList *list,LinkList r,LinkList q) {if(q==*list)//情況1:q指向鏈表的第一個結(jié)點{*list=q->next; free(q);}else //情況3:q指向的結(jié)點前驅(qū)結(jié)點的指針未知{for(r=*list;r->next!=q;r=r->next); //遍歷鏈表,找到q的前驅(qū)結(jié)點的指針if(r->next!=NULL){r->next=q->next; //從鏈表中刪除q指向的結(jié)點free(q);}} }

5、銷毀鏈表

使用鏈表之后需要銷毀它,因為鏈表本身會占用內(nèi)存。
code描述:

void destroyLinkList(LinkList *list) {LinkList p,q;p=*list;while(p){q=p->next;free(p);p=q;}*list=NULL; }

6、實例分析

要求:
輸入一組整數(shù)(大于10個數(shù)),以0作為結(jié)束標(biāo)志,將這組整數(shù)存放到一個鏈表中(結(jié)束標(biāo)志0不包括在內(nèi)),打印出該鏈表中的值。然后刪除該鏈表中的第5個元素,打印出刪除后的結(jié)果。最后在內(nèi)存中釋放掉該鏈表。

#include "stdio.h" #include "malloc.h" #include "conio.h"typedef int ElemType; //指針定義 typedef struct node {ElemType data; //數(shù)據(jù)域struct node* next; //指針域 }LNode, * LinkList;//***********創(chuàng)建鏈表******************// // LinkList GreatLinkList(int n) {//建立一個長度為n的鏈表LinkList p, r=NULL, list = NULL; //p:相當(dāng)于每次新建結(jié)點的暫存器,r:相當(dāng)于插入結(jié)點的上一個結(jié)點,永遠(yuǎn)指向原先鏈表的最后一個結(jié)點。list鏈表的頭指針ElemType elem; //獲取暫存數(shù)據(jù)int i; //定義累加器for (i = 0;i < n;i++){scanf("%d", &elem);p = (LinkList)malloc(sizeof(LNode)); //分配內(nèi)存,并將首地址送到pp->data = elem; //置入數(shù)據(jù)p->next = NULL; //指針指向NULL,暫時不考慮下一個結(jié)點if (!list) //如果鏈表為空,則新創(chuàng)建的結(jié)點就是該鏈表的第一個結(jié)點list = p;else //如果鏈表不為空,則將新建立的結(jié)點連接到之前鏈表的尾部r->next = p;r = p; //將p結(jié)點的數(shù)據(jù)賦給r}return list; //將鏈表的頭指針返回主調(diào)函數(shù),通過list就可以訪問鏈表中的每個結(jié)點,并進(jìn)行操作 }//*************插入結(jié)點************// // void insertList(LinkList* list, LinkList q, ElemType e) {//向鏈表中由指針q指向的結(jié)點后面插入結(jié)點,結(jié)點數(shù)據(jù)位eLinkList p;p = (LinkList)malloc(sizeof(LNode)); //生成一個新節(jié)點,由p指向它p->data = e;if (!*list) //如果鏈表為空{*list = p;p->next = NULL;} //當(dāng)鏈表為空的時候,q沒有意義,只能在頭結(jié)點后面插入第一個元素else{//當(dāng)鏈表不為空的時候,認(rèn)為q指向的結(jié)點一定存在//將q指向的結(jié)點的next域的值賦給p指向的結(jié)點的next域p->next = q->next;q->next = p;} } //通過這個算法同樣可以創(chuàng)建一個鏈表,因為鏈表為空時,list==NULL,可以自動創(chuàng)建一個結(jié)點。在下面創(chuàng)建其他結(jié)點時,只要始終將指針q指向鏈表的最后一個結(jié)點,就可以創(chuàng)建出一個鏈表//刪除結(jié)點 void delLink(LinkList* list, LinkList q) {LinkList r;if (q == *list)//情況1:q指向鏈表的第一個結(jié)點{*list = q->next;free(q);}else //情況3:q指向的結(jié)點前驅(qū)結(jié)點的指針未知{for (r = *list;r->next != q;r = r->next); //遍歷鏈表,找到q的前驅(qū)結(jié)點的指針if (r->next != NULL){r->next = q->next; //從鏈表中刪除q指向的結(jié)點free(q);}} }//銷毀鏈表 void destroyLinkList(LinkList* list) {LinkList p, q;p = *list;while (p){q = p->next;free(p);p = q;}*list = NULL; }void print_linklist(LinkList show_list) {while (show_list){printf("%d ",show_list->data);show_list = show_list->next;} } int main() {int elem = 0; //定義中間變量數(shù)據(jù)int i = 0; //定義累加器LinkList L, q; q = L = GreatLinkList(1); //創(chuàng)建1個鏈表結(jié)點,q和L指向該結(jié)點scanf("%d",&elem);while (elem) //循環(huán)地輸入數(shù)據(jù),同時插入新生成的結(jié)點,結(jié)束條件:輸入數(shù)據(jù)為0{insertList(&L,q,elem);q = q->next;scanf("%d", &elem);}q = L;printf("The content of the linklist\n");print_linklist(q);q = L;printf("\n Delete the fifth element\n");for (i=0;i<4;i++) //將指針q指向第五個元素{if (q == NULL) //確保此時鏈表的長度大于等于5,否則是非法操作{printf("The length of the linklist is smaller than 5");_getche();return 0;}q = q->next;}delLink(&L,q);q = L;print_linklist(q);destroyLinkList(&L);return 0; }

result:

總結(jié)

以上是生活随笔為你收集整理的【数据结构基础笔记】【链表】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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