C語言鏈表與單鏈表詳解
??鏈表是什么及鏈表的優(yōu)勢(shì)
鏈表是一種介于數(shù)組的另外一種數(shù)據(jù)結(jié)構(gòu):
我們知道數(shù)組可以存放很多的元素,這些元素都是呈線性排列,也就是一個(gè)挨著一個(gè)連續(xù)存放
但是當(dāng)元素足夠多時(shí),還能繼續(xù)正常的存放嗎?
事實(shí)上的不可以的,雖然系統(tǒng)的內(nèi)存足夠大,但是這些內(nèi)存不都是連續(xù)的,這就導(dǎo)致會(huì)出現(xiàn)沒有足夠的空間去存儲(chǔ)這些元素。
其次就是數(shù)組的大小需要你去申請(qǐng),如果你申請(qǐng)的空間足夠大,就會(huì)導(dǎo)致內(nèi)存的浪費(fèi)
而鏈表就很好的解決了這兩個(gè)問題
??鏈表的組成
鏈表的作用就是相當(dāng)與數(shù)組一樣,儲(chǔ)存你數(shù)據(jù)的
但又不同于數(shù)組,鏈表把每一個(gè)游離的數(shù)據(jù)進(jìn)行連接,連接的方法通過的是指針,也就是地址,
每一個(gè)鏈表都是由一個(gè)個(gè)結(jié)點(diǎn)組成,結(jié)點(diǎn)包含,一個(gè)是為我們存放數(shù)據(jù)的空間,另一個(gè)是存放下一個(gè)結(jié)點(diǎn)地址的空間,也就是所謂的數(shù)據(jù)域和地址域。
鏈表有時(shí)候包括了頭結(jié)點(diǎn),它是為了方便而設(shè)計(jì)的結(jié)點(diǎn),這個(gè)頭結(jié)點(diǎn)一般只包含地址域,也就是結(jié)點(diǎn)1的地址,一般情況下,頭結(jié)點(diǎn)的數(shù)據(jù)域一般無意義。
最后的結(jié)點(diǎn),指向的是NULL,用來限制鏈表的大小
??單向鏈表結(jié)點(diǎn)的定義
說完鏈表的組成是結(jié)點(diǎn),那單向鏈表的結(jié)點(diǎn)是如何定義的呢
struct Node //鏈表的結(jié)點(diǎn) { int data; //結(jié)點(diǎn)的值 struct Node *next; //下一個(gè)結(jié)點(diǎn)的地址 };
??單項(xiàng)鏈表的創(chuàng)建
//創(chuàng)建所需的結(jié)點(diǎn) struct Node* createList(int n) { struct Node* first, * t, * last; int i; first = (struct Node*)malloc(sizeof(struct Node)); //給第一個(gè)結(jié)點(diǎn)數(shù)據(jù)賦個(gè)值 scanf_s("%d", &first->data); last = first ; //在創(chuàng)建其他的結(jié)點(diǎn) for (i = n - 1; i > 0; i--) { //再首尾中間插入結(jié)點(diǎn).并賦值 t= (struct Node*)malloc(sizeof(struct Node)); scanf_s("%d", &t->data); last->next = t; last=t; } last->next = NULL;//防止野指針的存在 return first; }
??其中的first,last,還有t,都是指針變量,用來存放各個(gè)節(jié)點(diǎn)的地址
sizeof(struct listnode)
函數(shù)返回結(jié)構(gòu)體Node類型占用的字節(jié)數(shù)
malloc(sizeof(struct Node))
函數(shù)功能:系統(tǒng)從內(nèi)存的空閑空間中,申請(qǐng)存放一個(gè)結(jié)點(diǎn)的存儲(chǔ)空間。
(struct listnode *)malloc(sizeof(struct Node))
,函數(shù)返回一個(gè)指針(地址),指向剛分配給結(jié)構(gòu)體的第一個(gè)字節(jié)的地址。
malloc函數(shù)在頭文件stdlib.h中定義
??打印出鏈表各個(gè)結(jié)點(diǎn)的數(shù)據(jù)
//再創(chuàng)建函數(shù)進(jìn)行打印出各個(gè)結(jié)點(diǎn)的值 void printList(struct Node* first) { //把每一個(gè)字節(jié)數(shù)據(jù)域的都打印出來 struct Node* p = first; while (p != NULL) { printf("%d ", p->data); p = p->next; } printf("\n"); }
其中傳入函數(shù)的是結(jié)構(gòu)體指針
從第一個(gè)結(jié)點(diǎn)的數(shù)據(jù)域開始打印,到最后的NULL結(jié)束
(訪問下一個(gè)數(shù)據(jù)域不能用p++,因?yàn)殒湵聿皇沁B續(xù)的,地址也不是連續(xù)的,如果要訪問下一個(gè)數(shù)據(jù),需要用p = p->next)
??釋放向系統(tǒng)申請(qǐng)的空間
void destoryList(struct Node* first) { struct Node* p = first, *tmp; while (p != NULL) { tmp = p->next; free(p); p = tmp; } }
這里的 struct Node* p = first, *tmp;
就相當(dāng)于 struct Node*p=first;
struct Node *tmp;
??例題
??從鍵盤輸入一組整數(shù),創(chuàng)建單向鏈表,并輸出鏈表中的數(shù)據(jù)。
樣例輸入:2 5 7 6 3 4
樣例輸出:2 5 7 6 3 4
?? 解答如下:
#include<stdio.h> #include<stdlib.h> #define N 6 //鏈表 struct Node { int data; struct Node* next; }; //創(chuàng)建所需的結(jié)點(diǎn) struct Node* createList(int n) { struct Node* first, * t, * last; int i; first = (struct Node*)malloc(sizeof(struct Node)); //給第一個(gè)結(jié)點(diǎn)數(shù)據(jù)賦個(gè)值 scanf_s("%d", &first->data); last = first ; //在創(chuàng)建其他的結(jié)點(diǎn) for (i = n - 1; i > 0; i--) { //再首尾中間插入結(jié)點(diǎn).并賦值 t= (struct Node*)malloc(sizeof(struct Node)); scanf_s("%d", &t->data); last->next = t; last=t; } last->next = NULL;//防止野指針的存在 return first; } //再創(chuàng)建函數(shù)進(jìn)行打印出各個(gè)結(jié)點(diǎn)的值 void printList(struct Node* first) { //把每一個(gè)字節(jié)數(shù)據(jù)域的都打印出來 struct Node* p = first; while (p != NULL) { printf("%d ", p->data); p = p->next; } printf("\n"); } //釋放頭結(jié)點(diǎn)申請(qǐng)的空間 void destoryList(struct Node* first) { struct Node* p = first, *tmp; while (p != NULL) { tmp = p->next; free(p); p = tmp; } } int main() { struct Node* list; list = createList(N); printList(list);//輸出頭節(jié)點(diǎn)為list的鏈表 、、、、、、 destoryList(list); printf("\n"); return 0; }
到此這篇關(guān)于C語言鏈表與單鏈表詳解的文章就介紹到這了,更多相關(guān)C語言 鏈表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vs2022重新編譯opencv-python?cuda加速時(shí)報(bào)錯(cuò)的問題解決
本文主要介紹了vs2022重新編譯opencv-python?cuda加速時(shí)報(bào)錯(cuò),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04C語言中利用封裝好的函數(shù)實(shí)現(xiàn)英文字母的大小寫轉(zhuǎn)換
這篇文章主要介紹了C語言中利用封裝好的函數(shù)實(shí)現(xiàn)英文字母的大小寫轉(zhuǎn)換,需要的朋友可以參考下2017-10-10VSCode Linux的C++代碼格式化配置的實(shí)現(xiàn)
動(dòng)格式化代碼容易出現(xiàn)錯(cuò)誤,特別是當(dāng)代碼量較大時(shí),使用自動(dòng)格式化可以減少這種錯(cuò)誤的風(fēng)險(xiǎn),本文主要介紹了VSCode Linux的C++代碼格式化配置的實(shí)現(xiàn),感興趣的可以了解一下2023-10-10OpenCV實(shí)現(xiàn)車牌字符分割(C++)
這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)車牌字符分割,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11深入探討POJ 2312 Battle City 優(yōu)先隊(duì)列+BFS
本篇文章是對(duì)優(yōu)先隊(duì)列+BFS進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C++語言實(shí)現(xiàn)線性表之?dāng)?shù)組實(shí)例
這篇文章主要介紹了C++語言實(shí)現(xiàn)線性表之?dāng)?shù)組,實(shí)例分析了C++實(shí)現(xiàn)數(shù)組形式線性表的原理與方法,需要的朋友可以參考下2015-04-04