資料結構學習 鍊錶

2021-08-29 18:44:23 字數 3094 閱讀 9234

將從下面4部分進行介紹

首先介紹鍊錶是什麼,然後介紹為什麼定義鍊錶,接著是鍊錶的分類,最後簡單介紹一下鍊錶結點的插入與刪除方法

首先,在介紹鍊錶之前,我們先介紹一下什麼是順序儲存結構。我們知道資料在計算機中的儲存就像貨物在倉庫中的儲存一樣,不但占用一定的空間,還要有乙個標示儲存位置的位址。計算機通過該位址找到這個資料。 

那麼順序儲存結構,就是在儲存空間中,以一塊連續的記憶體位址開闢的空間來儲存內容的結構。 

那什麼是鏈式儲存結構呢?就是在儲存空間中,以一塊不連續的記憶體位址開闢的空間來儲存內容的結構。

我們看一下鏈式儲存結構示意圖,它就像一條鍊子一樣,其中每乙個元素就相當於這條鍊子的乙個小突起,看起來就像在繩子上的結一樣,我們稱這個結叫做結點。

我們所說的鍊錶,就是乙個典型的鏈式資料儲存結構。

我們為什麼要定義鍊錶這樣的鏈式儲存結構呢?

通常我們存放同種型別的資料時,可能會定義陣列來進行存放,陣列的優點在於便於對資料進行隨機訪問,因為陣列是屬於順序儲存結構,訪問其中的每個資料所需要的時間與這個資料所在的位置無關。

但是它也同樣存在弊端,就是陣列的大小在定義時要事先規定,不能在程式中進行調整,這樣一來,在程式設計中針對不同問題,有時需要3 0個大小的陣列,有時需要5 0個陣列的大小,難於統一。我們只能夠根據可能的最大需求來定義陣列,常常會造成一定儲存空間的浪費。

鍊錶就很好的解決的這個問題。它的特點是結構的長度十分靈活,都在在執行的時候現用現申請而不是像陣列那樣有固定的長度限制。而且它比順序儲存結構另乙個更方便的地方,是在資料插入或者刪除上,不用像陣列一類的順序儲存結構那樣進行很多次的資料移動,它只需要插入或者刪除其中的乙個節點就可以了。

鍊錶簡單可以分三類,分別是單向鍊錶、想象迴圈鍊錶和雙向鍊錶,他們的結構如圖所示,下面我對三種鍊錶分別進行介紹。

1.單向鍊錶:

首先是單向鍊錶,單向鍊錶是最簡單最基礎的鍊錶,它的指標域裡只有乙個指標變數指向下乙個結點,也就是說它只能從頭走到尾,進行單向遍歷。

我們看一下它的結構,最前面那個結點叫做表頭結點,它後面的這個叫做第乙個結點,表頭結點中資料域不存放內容,只是使用它的「next指標」指向真正的第乙個結點。

計算機從乙個節點中取出乙個資料後,根據該節點中存放的指標,找到下乙個節點的位置,如此迴圈下去。

單向鍊錶中最後乙個結點稱為表尾結點,它儲存的指標為「null」,代表單向鍊錶的結束。 

接下來我們舉個例子看一下,如圖乙個線性表a/b/c/d/e/f/g,如果是乙個單向鍊錶儲存結構,那麼看一下它的頭結點中的指標是31,應該指向的是第乙個節點的位址,我們就找到了a,a結點的指標域中儲存的指標是7,就指向下乙個結點,也就是b,如此類推,一直到最後乙個結點g,它的指標域是空,代表著鍊錶的結束。

我們可以把上述邏輯順序畫成用箭頭連線成的結點序列,就成了如圖所示的結構。

但是單向鍊錶有乙個顯著的缺點,就是從乙個已知節點出發,只能訪問該結點以後的結點,無法找到某個結點以前的結點。

為了解決這個問題,我們就引入了單向迴圈鍊錶。

2.單向迴圈鍊錶

單向迴圈鍊錶與單向鍊錶在結構上極為相似,不同的是,單向迴圈鍊錶的尾結點的next指向的不是null,而是鍊錶的第乙個結點。

由此可見,單向迴圈鍊錶是一種首尾相連的鍊錶。那麼在單向迴圈鍊錶中,從任一結點出發,都可以訪問到鍊錶中所有結點。

接下來,再舉乙個例子,就是經典的約瑟夫問題。

約瑟夫和另外40個猶太人被羅馬軍隊包圍在山洞中。猶太人決定寧願自殺也不要被俘。

他們商量乙個自殺的方法:41個人圍坐一圈,從第乙個人開始報數,每報數到3的人就自殺,下乙個人重新開始報數,如此迴圈下去,直到所有人死光。

約瑟夫不想自殺,那麼一開始他要站在什麼位置才能避免自殺?

我們看一下使用單向迴圈鍊錶來解決這個問題的主要程式。

void main()

jos.setbegin(); //開始模擬約瑟夫問題

int length = jos.getcount(); //原始人數

for (i = 1; i < length; i++)

cout << jos.getnext() << endle; //輸出最後剩下的人編號

}

單向鍊錶和單向迴圈鍊錶在尋找已知結點的前驅結點都是十分不容易的,必須從煉表頭開始進行順序遍歷鍊錶,直到某一結點的後繼結點為我們尋找的目標位置,當鍊表的數目很多時,這種尋找前驅結點的方法就會效率很低,於是又引入了雙向迴圈鍊錶。

3.雙向迴圈鍊錶

雙向迴圈鍊錶中,每個結點中都儲存兩個指標,乙個指向該結點的前驅結點,另乙個指向該結點的後驅結點。這樣的話,就可以沿著兩個方向對整個鍊錶進行遍歷。

雙向迴圈鍊錶就是通過這種雙指標形式實現了鍊錶的雙向迴圈。

最後,再簡單的說一下鍊錶結點的插入語刪除。

這裡我們以最簡單的單向鍊錶為例。

如圖所示,如果想要在這個位置插入乙個結點f,就只需要將b中的指標域改為指向f的位址,將f的指標域填寫為c的位址就可以了。

如果想刪除乙個結點,例如將結點b刪除,就把a結點的指標域改為指向的位址即可。 

對於單向迴圈鍊錶和雙向鍊錶的結點如果插入或者刪除的話,也是類似的情況,但要考慮所刪除的結點是最後乙個結點或者第乙個結點的情況。

資料結構學習 鍊錶

由於不必須按順序儲存,鍊錶在插入的時候可以達到o 1 的複雜度,比另一種線性表順序表快得多,但是查詢乙個節點或者訪問特定編號的節點則需要o n 的時間,而線性表和順序表相應的時間複雜度分別是o logn 和o 1 使用鍊錶結構可以克服陣列鍊錶需要預先知道資料大小的缺點,鍊錶結構可以充分利用計算機記憶...

資料結構學習 鍊錶結構

儲存結構定義 struct node typedef struct node ptrtonode typedef ptrtonode list typedef ptrtonode position struct node 書寫 package thedatastructureaboutlinked ...

資料結構學習筆記 鍊錶

表示式的計算 表示式的計算涉及到棧的操作 對於表示式 a b c d e f 演算法 用到兩個棧,分別是符號棧和運算元棧。輸入表示式時,為了表示表示式輸入完畢,在表示式的最後加上 號,也就是說輸入的表示式為 a b c d e f 首先設定各個符號的優先順序,和 的優先順序為0,也就是最低的 和 的...