資料結構自學筆記 C語言 鍊錶

2021-09-24 20:28:43 字數 3818 閱讀 9468

從上一節內容裡可以看出,線性表的順序儲存結構的特點是邏輯關係上相鄰的兩個資料元素在物理位置上也相鄰,因此可以通過實體地址的關係來隨機訪問表中任意元素,它的儲存位置可以用乙個簡單的直觀的公式來表示。然而從另一方面來看,這個特點也導致了這種儲存結構的弱點,在插入或者刪除操作時需要移動大量元素。這節我們學習線性表的鏈式儲存結構

線性表的鏈式儲存結構其實就是我們學c語言時最難的鍊錶,他的特點是可以用一組任意的儲存單元來儲存資料元素,單元可以是連續的也可以是不連續的。那麼資料元素間的關係如何確定呢?用乙個類似與鍊子的東西。鍊錶中的每個資料元素我們稱之為結點,每個結點包括兩個域:資料域和指標域。資料域顧名思義,就是用來儲存資料的,指標域是用來做什麼的,它儲存了下乙個節點的位址,這個位址可以叫作指標也可以叫作鏈,也就很巧妙的將結點聯絡了起來。總結一下鍊錶的優缺點,優點:它是一種動態結構,整個儲存空間為多個鍊錶公用;不需要預先分配儲存空間。缺點:指標占用額外空間,不能隨機訪問,查詢速度慢 ;在單鏈表的最後乙個元素之後插入元素時需要遍歷整個鍊錶。下面我們對比一下線性表的順序儲存結構和鏈式儲存結構。

左邊是鍊錶的結構體,右邊是順序表的結構體。兩個結構體中都有和資料儲存有關的,但鍊錶用基本資料型別就可以了,而順序表要用指標。鍊錶的另乙個結構體成員是結構體指標,線性表的剩下兩個成員是表長和元素數量。個人覺得對比學習的方法是有助於知識點理解的很好的乙個方法。大家可以先思考一下為什麼這兩種線性表的結構體組成是這樣的。

順序表:我相信大部分初學者思考完是一臉懵逼的,現在我們整理一下思路。先說順序表。我們說了順序表是通過實體地址的關係來確定資料元素之間的元素,所以在建立順序表時我們要先申請出一片實體地址相連的空間,然後去對號入座,逐個儲存資料。那我申請多大的空間呢,線性表表長(listsize)就可以告訴我們申請多大,通過初始化資料先申請一片空間,假如設定的listsize是100,那麼哪怕我只想存乙個元素,但我也需要申請出100個資料元素大小的空間,等到存滿了之後,可以繼續申請,但不會是一次申請乙個,一般都是一次申請一片,存滿了再申請一片。資料元素個數(length)是用來做什麼的,顧名思義元素個數就是告訴我們在順序表中存了多少個元素,知道了有多少元素才可以取元素,在範圍外取元素時拒絕,不然會取出一些亂七八糟的數。比如我一共有8個資料元素,你非要問我第9個是什麼,如果程式不夠健壯的話,也會取出乙個值,但這明顯是不對的,有了資料元素個數我就可以拒絕你的無理要求了。length還有乙個作用就是判斷是否需要繼續申請空間,在申請前先把length加一,看看是否超過了表長,超過了就繼續申請儲存空間,繼續申請空間時用realloc函式,如果原先申請的位址還可以繼續連續,那就繼續申請,要是不夠了,那就帶上前面資料一起,再重新找一片連續的地方。還有乙個結構體成員是資料指標,為什麼是指標呢,因為我們是通過實體地址來儲存啊,要取位址的值當然要用指標了。順序表結構體中的結構體成員的作用就都用大白話解釋完了,可以發現乙個順序表只需要乙個結構體就好了。

鍊錶:鍊錶的結構體中只有兩個資料成員,對應我們的資料域和指標域,資料域用來存資料,用基本資料型別就好了,為什麼不用指標呢?因為沒必要。。指標域是乙個結構體指標,用來指向下乙個結點。也就是說我要儲存多少資料,就要有多少結點,也就要有多少個結構體。在這裡可能有人會問為什麼不一次申請一大片,因為鍊錶對實體地址沒要求啊,存乙個申請一次就好了,在哪都無所謂。也不知道我有沒有說清楚,都是大白話,力求能講明白,不然就跟看書沒啥區別了。

順序表的優勢在於找,缺點在於插入和刪除。而鍊錶正好反過來了,插入刪除非常容易,查詢非常難。因為你只知道乙個頭節點,查詢時要從頭結點找下個節點,下個節點再找下個的下個,按最壞的情況來看,如果你要找第n個資料,那麼你就要找n次,時間複雜度就是o(n)。插入和刪除的時間複雜度也是o(n),因為時間都花在找節點上了,找完只要把前乙個節點的指標指向要插的節點上,然後要插的節點的指標指向原先的下乙個節點上就好了。鍊錶這個名字還是很形象的,如果還是理解不了你就想一下,在一串鍊子中間加乙個新的,你要怎麼操作,和資料結構中的鍊錶道理是一樣的。

接下來也要開始上程式了,挑了幾個:鍊錶的正向建立、反向建立、獲取特定節點資料、刪除特定節點、兩個從小到大排列的鍊錶合成乙個鍊錶;在上程式前先說幾個要注意的點。

typedef struct linklistlinklist,*linklist1;

這種結構體建立的意思是linklist可以用來建立結構體,struct linklist也可以用來建立結構體,linklist1用來建立結構體指標,linklist也可以用來建立結構體指標,struct linklist *也可以(乙個星號,之所以寫了兩個是因為格式問題)。可能有點繞,在這就不說了,看不懂的話可以查查資料。

1.c語言要求在使用結構體指標的時候必須要初始化,不然要報錯run-time check failure #3 - the variable 『l2』 is being used without being initialized.所以建立結構體指標需要傳到子函式中,後要在建立完申請一段空間讓指標指過去。在上一節的程式中我是先建立了乙個結構體,然後讓指標指向這個結構體,乙個道理。

2.鍊錶中的結構體指標指向的是本身的結構體。typedef重新命名後的結構體建立方式不能用,因為typedef語句還沒執行完。所以只能用struct linklist,這個問題搞了很久。

3.因為結構體指標在傳入子函式前必須初始化這個問題實在是太搞了,後來想了想為什麼不在子函式中建立結構體指標然後把它返回呢,是可以的,在正向建立就是用的這種方法。但仔細想了想可能作者想讓我們感受一下靠指標做形參來改變指標內容的感覺吧。

#include

//printf函式

#include

//malloc函式

//struct linklist next;//在結構體還沒定義完之前,編譯器不知道該型別所需多大空間,報錯

//linklist *next;//typedef語句還沒執行完,報錯

typedef

struct linklistlinklist,

*linklist1;

linklist1 listcreat1

(int n)

//正向建立

return l;

}void

listcreat2

(linklist1 l,

int n)

//反向建立

//return l;

}int

getelem

(linklist1 l1,

int n,

int*e)

//獲取特定位置

if(j>n||

!p)return-1

;else

}int

delelem

(linklist1 l1,

int n)

//刪除特定位置

else}if

(!p->next||n

return-1

; q = p->next;

p->next = q->next;

return1;

}void

listmerge

(linklist1 l1,linklist1 l2,linklist1 l3)

//合併鍊錶

else}if

(p1)p3->next = p1;

else p3->next = p2;

free

(l2)

;free

(l1);}

intmain()

//printf("%d ",*e);

}

C語言鍊錶基礎自學筆記

為了複試開始複習c語言的一些程式設計技巧,今天覆習c鍊錶。1.鍊錶的結構體 typedef struct nodenode 2.建立乙個有n的節點的鍊錶 node linkcreate int n end next null 最後一位需要null,遍歷的時候while p 就行 return hea...

資料結構(C語言) 單向鍊錶

c語言的單向鍊錶,就是在乙個將一些資料放在乙個結構體裡,然後在結構體裡加 struct next 的成員,用於指向下一結點。引用時,建立乙個臨時的結構體變數進行引用。如原結構體變數為 struct p 則 可建立 struct temp,然後 for temp p temp next null te...

資料結構 單向鍊錶 C語言

chainlist.h include include typedef struct nodechainlisttype chainlisttype chainlistaddend chainlisttype head,data data 新增節點到鍊錶末尾 chainlisttype chainl...