資料結構 單鏈表

2021-10-10 15:16:37 字數 4450 閱讀 6121

線性表:同一種型別的有順序的一組資料元素

線性表的形式:順序表、鍊錶

順序表:表中元素按順序放在一大塊連續的記憶體中,元素中的順序由儲存順序來表示

鍊錶:表中元素放在一系列的結點中,通過連線構造。結點可以連續也可以不連續。

頭結點的設立是為了操作的統一和方便,是放在第乙個元素的節點之前,它的資料域一般沒有意義,並且它本身也不是鍊錶必須要帶的。那設立頭節點的目的是什麼呢?其實就是為了在某些時候可以更方便的對鍊錶進行操作,有了頭結點,我們在對第乙個元素前插入或者刪除結點的時候,它的操作與其它結點的操作就統一了。

頭指標顧名思義,是指向鍊錶第乙個結點的指標,如果有頭結點的話,那麼就是指向頭結點的指標。它是鍊錶的必備元素且無論鍊錶是否為空,頭指標都不能為空,因為在訪問鍊錶的時候你總得知道它在什麼位置,這樣才能通過它的指標域找到下乙個結點的位置,也就是說知道了頭指標,整個鍊錶的元素我們都是可以訪問的,所以它必須要存在,這也就是我們常說的標識,這也就是為什麼我們一般用頭指標來表示鍊錶。

n 個結點鏈結成乙個鍊錶,因為這個鍊錶中的每個結點中只包含乙個指標域,所以又叫單鏈表。單鏈表的第乙個結點的儲存位置叫做「頭指標」,最後乙個結點的指標為「空」,一般用 「^」 表示。

不帶頭結點的單鏈表:

帶頭結點的單鏈表:

空鍊錶:

為了方便後續的操作,我們一般會先定義乙個簡單的結點類:

class

node

(object):

def__init__

(self,data)

: self.data = data

self.

next

=none

首先我們先來建立乙個鍊錶類:

class

linklist

(object):

def_init_

(self)

: self.head = node(

none

)#判斷鍊錶是否為空

defisempty

(self)

: p=self.head #頭指標

if p.

next

==none

:print

("list is empty"

)return

true

return

false

#列印鍊錶

defprintlist

(self)

:if self.isempty():

return

false

p = self.head

while p:

print

(p.data,end='')

p=p.

next

1.建立單鏈表

建立單鏈表的過程其實就是乙個動態生成鍊錶的過程,說簡單點就是從乙個「空鍊錶」開始,依次建立各個元素的結點,並把它們逐個插入鍊錶,時間複雜度為 o(n):

def

initlist

(self,data)

self.head = node(data[0]

)#頭結點

p = self.head #頭指標

for i in data[1:

]:node = node(i)

p.next

= node

p = p.

next

2.計算單鏈表的長度

在使用鍊錶的時候,經常需要求表的長度,為此我們可以建立乙個球表長的函式,這個函式就是從左到右掃瞄,遍歷表中的所有結點並完成計數,時間複雜度為 o(n):

def

lengthlist

(self)

:if self.isempty():

return

0 p = self.head

cnt =

0while p:

cnt +=

1 p = p.

next

return cnt

3.單鏈表的插入

假設我們要將結點 s 插入到 結點 p 的後面,只需要將結點 s 插入到結點 p 和 結點 p.next 之間即可.

單鏈表結點的插入根本不需要驚動其它結點,只需要讓 s.next 和 p.next 的指標稍作改變即可。這裡一定要切記,插入操作的順序不能改變,至於為什麼,你可以拿起紙筆手動的畫一下,結果一下子就會出來(對於單鏈表的表頭和表尾的特殊情況,操作是相同的)。

#單鏈表的插入(在第 s 個結點後面插入 data)

definsertlist

(self,s,data)

:if self.isempty(

)or s <

0or s > self.lengthlist():

print

("insert failed!"

)return

p = self.head

index =

1while index < s:

p = p.

next

index +=

1 node = node(data)

node.

next

= p.

next

p.next

= node

4.單鏈表刪除

看完插入,我們現在再來看看單鏈表的刪除。假設我們想要刪除乙個結點 q,其實就是將它的前繼結點 p 的指標繞過 q,直接指向 q 的後繼結點即可,具體操作如下圖所示:

#單鏈表的刪除(刪除第 s 個結點)

defdeletelist

(self, s)

:if self.isempty(

)or s <

0or s > self.lengthlist():

print

("delete failed! "

)return

p = self.head

index =

1while index < s:

pre = p

index +=

1 p = p.

next

pre.

next

= p.

next

p =none

由 p = none 可以看出,在 python 中,只需要簡單的將指標賦值為 none,就拋棄了鍊錶原有的結點,python 直譯器的儲存管理系統會自動**不用的儲存。

5.單鏈表的讀取

在順序結構中,我們想要獲取任意乙個元素的儲存位置是很容易的,但是在單鏈表中,第 i 個元素到底在哪我們一開始沒辦法知道,只能傻傻的從頭開始找,所以在對於單鏈表獲取第 i 個元素的操作,演算法上相對麻煩一些。

#單鏈表的讀取(獲取第 s 個結點的值)

defgetlist

(self, s)

:if self.isempty(

)or s <

0or s > self.lengthlist():

print

("read failed! "

)return

p = self.head

index =

1while index < s:

index +=

1 p = p.

next

print

("第 {} 個值為 {}"

.format

(s, p.data)

)

從上面的**我們可以很清楚的看出,單鏈表獲取第 i 個元素就是從頭開始找,知道第 i 個元素為止,所以我們可以很容易的估算出它的時間複雜度是 o(n)。任何事物都不是完美的,有好的地方就有壞的地方,元素的讀取就是單鏈表美中不足的地方之一。

資料結構單鏈表

初學資料結構,貼段自己編寫的單鏈表程式,希望自己能夠一直以強大的學習熱情持續下去!自勉!2012年3月30日 於大連 include using namespace std typedef struct node linklist,node linklist makelist int n void ...

資料結構 單鏈表

今天浪費了好多時間,也許是心裡想著明天的考試吧 可自己也知道這次的考試,自己畢竟過不了了,只好等到今年11月份,想想那時自己已經大三了 還有那麼多時間嗎!很懊惱今天不知怎麼回事,感嘆環境真的可以影響乙個人,真的可以 把今天的學習筆記寫下來,沒有進行好好的整理,這回單鏈表的功能較多,操作比較散,最後乙...

資料結構 單鏈表

實現乙個單鏈表 1 查詢 查詢第index個節點 查詢指定的元素 2 插入 將指定的元素插入到第index個節點上 3 刪除 將第index個節點刪除 規律 刪除和新增元素前務必儲存兩個元素的位址引用資訊 public class mylinkedlist 記錄鍊錶結構的頭結點位址引用 privat...