如果想知道什麼是鍊錶,你得先知道什麼是順序表。
1. 順序表就是物理結構上連續。同時,在邏輯結構上也是連續線性的。經典中的經典就是陣列!
物理結構就是他們的位址是連續的。邏輯結構是連續線性的,只要你按照他們的小標走總是可以找到他們的位置。
那麼鍊錶是什麼?為什麼會有鍊錶的存在?
鍊錶就是一環扣一環的結構,在邏輯上與順序表一樣是線性的,但是在物理結構上與順序表不同;
大家一開始看這個肯定有點懵,為什麼是這樣?先看這張圖有個基本印象,下面我還將用這種圖給大家一一講解
我們用大金鍊子來形容鍊錶真是在好不過了,但是鍊錶僅僅只是邏輯上是線性的,不像大金鍊子物理上也是連在一起。實際上,鍊錶的儲存一般是在堆區,這塊地方是動態開闢的,所以我們對於資料的儲存和釋放也更加靈活,對比於順序表儲存的頭插法,順序表要先將所有元素往後移,才能存到第乙個位置,鍊錶直接把新節點指向之前的第乙個節點,再把之前第乙個節點指向新的節點就可以了,方便很多。刪也是如此。講到這可能真要瘋了,你之前講的是什麼,這不是鍊錶入門嗎?放心我一般講完就會放個圖給大夥理解理解。
這樣看應該是能理解的,不需要深入,如果你要研究一下這方面的東西,我建議你去看看《程式設計師的自我修養》
紅色是代表之前的狀態,黑色是之後的狀態;如果第一步跟第二步顛倒了,那我們就失去了head紅色指向的空間,所以鍊錶很講究順序問題
2. 鍊錶的存在就是為了彌補上順序表的缺點,順序表不能很好的利用空間,有可能會造成空間浪費;鍊錶一般的增刪都比順序表要高效;
之前說了,鍊錶是按順序表的缺點來設計的,那其實它的用途就是為了彌補上順序表的不足。
順序表無法做到任意插入刪除的時間複雜度為o(n),而鍊錶的插入刪除,就直接找到你要查詢的值,然後簡單的換一下指向就可以了。
鍊錶的空間使用十分靈活,你要用就開乙個,不用就銷毀乙個,而順序表一旦開闢了空間,刪除資料其實是沒有把資料記憶體釋放的,順序表對於空間的使用很難把握。
鍊錶鍊錶,那自然少不了開頭的第乙個吧?所以我們先定義乙個頭。那鍊錶的身體怎麼表示?對了,我們就模仿大金鍊子一樣,給乙個乙個環當成乙個點,我們就暫時稱為節點吧。開頭第乙個好像也可以是個節點,那我們是不是可以抽象出乙個東西,在c語言中,好像沒法直接定義這樣的東西......對了,結構體,就是結構體,我們可以用結構體。那我們就先開始嘗試用結構題來定義節點吧!
typedef struct slistnode
sltnode;
大致寫成了這樣,我覺得很完美,跟上面想的結構一模一樣。問問自己,這樣寫對嗎?......好像有點不對,位置應該是個位址,不應該是個結構體變數,額,我們要改進
typedef struct slistnode
sltnode;
這樣總可以了吧,很完美了,我想說的是,對,挺完美,但是鍊錶難道只能存int型資料嗎? ...答案顯而易見,不止。那讓我們最後來建立一次
typedef int slistelemtype;
typedef struct slistnode
sltnode;
這樣寫,到時我們想寫什麼就去改slistelemtype 的自定義型別就夠了上面定義好了鍊錶的節點,現在我們開始,試著往裡面加點資料試試,先畫個圖
有點不行這樣,第乙個節點如果進去就存資料,那我們要是只要乙個不存資料的鍊錶怎麼表示?再畫個圖
這樣可以了,我們大功告成了乙個不存資料的鍊錶
接下來,我們放資料
這種情況是存入乙個空的鍊錶,如果是之前就有資料了呢?圖中的星號表示是最新的意思
如果有乙個以上的資料呢?圖中的星號表示是最新的意思
圖中的星號表示的是最新的意思
稍微抽象出來,除了空,乙個資料的存入跟乙個資料以上的存入是一樣的邏輯;
1.空就是直接把頭指向新節點就可以了;
2.但是,乙個資料的存入跟乙個資料以上的存入不同,我們先把新節點指向了舊的頭結點,再把舊的頭結點指向新節點就可以了;舊的頭結點就是每個圖中的head,帶星號的head是存入資料後最新頭結點
我們來嘗試寫寫**吧!,這裡為了減少大家的負擔我就把建立節點寫成了buyslistnode(x),大家不用在意這個函式的細節,只需知道這個函式功能就是建立乙個節點即可,跟圖上newnode的是吻合
void slistpushfront(sltnode* phead, slistelemtype x)//傳參傳的是頭結點,跟你要加進來的資料
}
這裡寫的**完全按照上圖的內容寫出來的,->是結構體指標訪問結構體成員的操作符;
細心的同學可能就發現了空的情況好像跟第二種也沒什麼區別,因為當newnode->next = phead;如果phead = null,其實就是在給新節點的next指向了null,而本身新節點裡的next就是指向null,所以可以合併。
void slistpushfront(sltnode* phead, slistelemtype x)//傳參傳的是頭結點,跟你要加進來的資料
如果你認為寫成這樣就可以了,那還是差了一點火候,不過如果你可以理解這個函式為什麼這樣寫,其實就差不多了;ok,為什麼還不行,是因為你用了phead = newnode這個賦值語句,一般傳參其實不是把實參給函式,而是賦值一備份給函式,所以如果你想改phead的值,那得傳二級指標。更新一下**
void slistpushfront(sltnode** pphead, slistelemtype x)//傳參傳的是頭結點的位址,跟你要加進來的資料
如果你不理解的話,可以試著自己像這樣畫個圖,我相信你一定可以整的明白。這個儲存方法就是最經典的單鏈表頭插法,你如果繼續深入學習,你還會學尾插法,雙鏈表等等,這裡我們只是入門,只是帶你大概清楚鍊錶是怎麼來的,及一些簡單的使用現在我們重新看一下這張圖這就是鍊錶的邏輯結構,節點就是結構體變數,它不是指標,每個節點都有自己的位址,但是第乙個頭結點,我們一般是定義成乙個指標,如果你不想定義成指標也可以,就是操作鍊錶沒那麼方便,通過訪問節點裡存放的位址,我們就可以訪問下乙個節點,依次操作,就可以找到所有儲存的資料,這也就是我們說它很像大金鍊子,但不完全是。
之後我可以會繼續講解,看情況吧,這期就這樣了,雖然做的不咋地,如果你看完這篇覺得你對鍊錶還挺感興趣的,也算達到我的目的了
鍊錶學習1 C 指標的理解(1)
1.c 中指標的主要作用是指向node 讓你知道你現在所指的位置和node 是哪個,讓你關注於你現在要處理的node str next的作用是為了連線鍊錶 防止鍊錶斷開 2.p next的變化,就是乙個斷捨離的過程 斷了以前的,指向現在的。3.指標的賦值如何理解 我指著它 node 呢,你也快指它啊...
c語言 鍊錶 C語言之鍊錶入門
鍊錶三要素 1 頭指標 head 是用來說明鍊錶開始了,頭指標就代表鍊錶本身 所以以後要訪問鍊錶,就要訪問頭指標 2 結點 node 鍊錶中每乙個結構體變數 3 尾指標 用來說明鍊錶的結束 它是乙個空指標,null include includetypedef struct stud 定義了乙個結構...
1C語言例項講解選擇語句的使用
目錄 用圖示來表示 if else 語句其實就是當條件為真的時候執行某一部分的內容,當條件為假的時候就跳過這部分的內容接著往下執行。if 表示式 else if else語句最常見的流程就是上面這樣。當表示式為真的時候執行語句塊1的內容,當表示式為假的時候執行語句塊2的內容。那麼可能有些人就會問了,...