對於線性結構還有一種實現模式,就是鍊錶,相比於陣列,鍊錶的優勢在於,他理論上沒有最大的規模,不像陣列需要規定乙個明確的最大值。而且插入刪除操作相比於陣列來講比較容易,但是實現起來比較花裡胡哨,需要一段時間去訓練,實現原理還是很簡單的。
注意:鍊錶的操作建議同學畫圖理解。
我們是這樣建立鍊錶的,首先是建立一種叫做結構體的東西,這種東西呢將各種基本結構融合在一起,然後進行乙個封裝,這一點c做的相對沒有那麼強,封裝只能選擇假裝已經封裝了哈。。畢竟c面向過程。對於鍊錶就需要這樣一種封裝,即製作乙個節點結構體,這種結構體具有乙個特點,就是像乙個大頭釘,頭是橡皮做的,釘是純鐵工製造。我們的目的就是讓這些大頭釘乙個釘子扎在橡皮裡,橡皮上的釘子釘在下乙個橡皮裡,就這麼迴圈往復地扎下去,最後乙個沒地扎,那就扎地里,也就是所謂的置空。
#include
typedef
struct node
node,
*pnode;
//pnode就是指指向鍊錶節點的指標pointer node
intmain()
linklist 就是代表乙個鍊錶,不過這個鍊錶是空的,我們需要對其進行初始化。有兩種初始化的形式,建議大家熟記運用。
首先是頭插法,基本思想是,你不是有乙個頭節點*linklist嘛,然後我每次新增進去的節點都放在最前面(最前面即是指linklist->next的位置)。
具體操作和插入乙個節點的思想是一致的,如果我想將ptr建立的節點插在某節點n的後面成為n的後繼,首先節點的後繼指標應該是n的後繼,先這麼做不至於鍊錶斷掉,然後再讓n的後繼換成ptr指向的節點,如果顛倒,那n的後繼改變之後,就相當於將原來n的後繼扔掉了,沒有指標可以找到這一塊記憶體,這塊記憶體就洩漏了,這是很危險的,這也是一般不建議使用鍊錶操作的原因。
兩種方法乙個思想,先用乙個指標ptr建立節點,再用鍊錶指標將這個節點串進去.
頭插法
pnode ptr =
(pnode)
malloc
(sizeof
(node));
ptr->data =
100;
//建立節點
ptr->next = linklist->next;
//後繼是頭節點的後繼,即原來的最前端。
linklist->next = ptr;
//頭節點指向新的最前端
很簡單吼,當然,如果需要重複插入,迴圈就好了
尾插法相對的一氣呵成,一般沒有一次插乙個的,因為如果想尾插,一般需要乙個尾指標,但是我寫的這個是不帶尾指標的,所以尾插法更適合一氣呵成直接建立乙個長度為假設10的鍊錶。
基本思路就是設計乙個尾指標toil,toil指向的就是鍊錶的最後乙個節點,然後每次操作就操作這個節點,先用ptr建立乙個節點之後,再讓toil的後繼插在ptr指向的節點上面就闊以了,當然最後需要後移toil指標。
int i;
pnode toil = linklist;
//剛開始鍊錶最後乙個節點是頭節點。
pnode ptr =
null
;//指標初始化為空,盡量不要有產生野指標的機會
for(i =
0; i <
10; i++
) toil->next =
null
;//這句純屬是給不寫ptr->next = null的人寫的,最後的指標一定要置空
尾插法相對複雜一點,但是也不算太複雜,而且基本成定式,照著寫就ok
對於一些奇怪的結構,我們都可以在這些操作的基礎之上建立起來,比如環形鍊錶,那麼就是本來我是要將最後乙個節點的後繼置空的,但是我沒有,我將這根針直接插在了頭節點上而已。
鍊錶的增刪改查相對於陣列而言要麻煩一些,鍊錶不支援隨機儲存,所以要在定位上花費很多時間,但是我們為什麼學呢,主要是因為這是一種結構,是其他結構實現的基礎,而且不限制最大規模,還是靈活運用吧。
我們只對增刪最前端的節點做一些說明
從前邊新增乙個節點即頭插法建立鍊錶的操作,不再作解釋,我們介紹一下如何刪除乙個最前端的節點。
首先要說明,所有的節點都是靠動態記憶體分配的,記憶體相當於借的,有借有還,再借不難,程式結束之前,應該將所有的動態記憶體原數歸還給計算機。
所以只要有malloc,就應該有free,這是乙個好習慣。
所以刪除之後的那個節點應該還給計算機,具體操作,我先使用乙個指標ptr插到我想刪除的節點上,這樣節點被取出時至少我還知道他在哪。然後我直接像陣列那樣,不把他當個玩意看,頭節點的後繼指標直接繞過這個節點插到這個節點的後繼上,然後再給這個節點還回去,大致就是這麼個過程,具體操作如下
pnode ptr = linklist->next;
//指向我想刪除的節點
linklist->next = linklist->next->next;
//繞過這個節點
free
(ptr)
;//釋放記憶體
所以,在程式結束之後應該有個清空鍊錶的操作,演示一哈
pnode ptr =
null
;while
(linklist->next)
//只要頭節點後邊還有東西
free
(linklist)
;//最後別忘了清除頭節點
鍊錶也有他的遍歷操作,也比較簡單,如果說陣列的遍歷是
int i;
for(i =
0; i < n; i++
)
的話,那麼鍊錶的操作模擬一下就可以得到
pnode ptr;
for(ptr = linklist->next; ptr !=
null
; ptr = ptr->next)
是不是很簡單
最後,提醒孩子們,鍊錶的插入刪除操作如果想要寫函式的話,記得傳二重指標。
線性鍊錶的順序儲存結構基本實現(C )
又有一段時間沒有更新部落格了。在家久了變的異常敏感,什麼都會去想,想多了又會自閉。不管咋樣,生活還在繼續,無法逃避。該面對的還是要直面,就希望安穩畢業,順利入職。開始資料結構與c 的混合訓練模式。看別人的 寫 好像啥都懂。拿開自己寫,好像啥都不知道。先從最基本的線性鍊錶的順序儲存結構學起吧。先上 包...
資料結構 線性鍊錶的c語言實現
鍊錶實現的邏輯分析 為了實現業務結點的靈活定義,我們需要定義單獨定義鍊錶結點來實現鍊錶的串接與查詢,而要讓業務結點包含鍊錶結點,以實現通過鍊錶結點將業務結點串接起來。而為了實現業務結點與鍊錶結點的位址統一,我們在定義業務結點時要將鍊錶結點包含在頭部,以實現目的。示意圖如下圖所示。鍊錶結點定義 typ...
資料結構C語言實現 線性鍊錶
declaration.h ifndef declaration h included define declaration h included define true 1 define false 0 define ok 1 define error 0 define infeasible 1 ...