關於鍊錶的一些操作總結

2021-08-28 16:41:54 字數 3769 閱讀 5646

這是乙個簡單的鍊錶操作問題,在leetcode上面有52.7%的通過率,難度是簡單。但是還是想在這裡基於python做一下總結,順便總結一下鍊錶的各種操作。

首先先看一下leetcode上面的題目:

反轉乙個單鏈表。

示例:輸入: 1->2->3->4->5->null

輸出: 5->4->3->2->1->null

高階:你可以迭代或遞迴地反轉鍊錶。你能否用兩種方法解決這道題?

看完了題目,很直白,就是轉過來。我們嘗試對這道題進行解決。這道題用python至少會有三種解決方案。

首先是鍊錶的資料結構定義:

# definition for singly-linked list.

class

listnode

:def

__init__

(self, x)

: self.val = x

self.

next

=none

將鍊錶遍歷進list中,然後利用切片反轉list,再將list填充到鍊錶中即可。這是最簡單的一種思考邏輯,但是也比較消耗效能。時間和空間複雜度都為o(n)。

def

loop

(head)

: temp =

while head is

notnone

: head = head.

next

temp = temp[::

-1]for i, n in

enumerate

(temp)

:if i +

1<

len(temp)

: n.

next

= temp[i +1]

else

: n.

next

=none

return temp[0]

if temp else

none

另一種迭代演算法,是一種純粹交換的迭代,筆者這裡擷取了leetcode速度最快的一種。

def

reverselist

(head)

:"""

:type head: listnode

:rtype: listnode

"""ifnot head:

return

none

it = head; jt = head.

next

it.next

=none

while jt:

tmp = it

it = jt

jt = jt.

next

it.next

= tmp

return it

這一波交換操作,我們可以畫個示意圖就知道他的交換是一種怎麼樣的交換。

從圖中可以看出,迴圈的作用就是將反向指標進行儲存。同時令將指標轉向的功能。

最後一種方案是採用遞迴的方式進行鍊錶反轉。這種方式也需要一定的理解。我們先展示一下**。

def

reverselist

(head)

:"""

:type head: listnode

:rtype: listnode

"""if head is

none

or head.

next

isnone

:return head

end = reverselist(head.

next

) head.

next

.next

= head

head.

next

=none

return end

這種解法其實理解起來只有兩部分內容,傳遞反向指標和進行指標反向拼接。我們先來理解一下指標反向拼接這個操作。

1 -> 2 -> 3 -> 4 -> none

依次:3(head) -> 4(head.next) -> 3(head.next.next)

3 -> none

如此迴圈即可將鍊錶反轉過來。但是還有個關鍵就是將最後乙個指標傳遞出來。我們可以看到之前的**中,end傳出來後是一直沒有做任何操作的。不停的return出最後乙個指標。所以就將最後乙個指標傳遞了出來。

以上就是鍊錶反轉的3中方法。除此之外還想寫一些鍊錶的簡單操作。

何為快慢指標,即對鍊錶進行兩個不同步頻的指標標記遍歷。最經典的是慢指標走一步,快指標走兩步。

快慢指標有很多的應用,比如說:

判斷乙個鍊錶是否存在環。

def

hascycle

(head)

:"""

:type head: listnode

:rtype: bool

"""if head is

none

or head.

next

isnone

:return

false

fast, slow = head.

next

.next

, head.

next

while fast is

not slow:

if fast is

none

or fast.

next

isnone

:return

false

fast = fast.

next

.next

slow = slow.

next

return

true

兩個指標併排走,如果有環的話快指標最終會指向慢指標的位置。沒有環的話,快指標會指向none後退出。

當然這道題的解法不止這一樣,還可以利用set進行判斷。

輸出鍊錶中的倒數第k個節點

這道題利用快慢指標的思路是這樣的。定義兩個指標,第乙個指標向前走k-1步;第2個指標保持不動;到第k步時第2個指標也開始移動。由於兩個指標始終保持著k-1的距離,所以當快指標到達末尾時,慢指標剛好指向倒數第k個。

def

count_back

(head, k)

:if head is

none

:return head

fast, slow = head, head

for i in

range

(k -1)

: fast = fast.

next

if fast is

none

:return

none

while fast is

notnone

: fast = fast.

next

slow = slow.

next

return slow

這是關於鍊錶的兩種比較簡單的操作,反轉和快慢指標。挺常見的面試題,在這裡做一些記錄分享。

關於鍊錶的一些總結

1.在鍊錶頭部新增空頭以消除頭部特殊判斷比較常見,用於刪除和新增元素,啞結點的意思就是在head第乙個節點之前設立乙個節點。2.因為鍊錶的操作有限,所以很多時候我們可以把鍊錶中的元素儲存在陣列中,進行操作。3.鍊錶從前往後遍歷元素簡單,但是從後往前遍歷元素確實困難重重,所以我們可以使用棧來儲存資料,...

關於鍊錶操作程式設計實現的一些總結

鍊錶是一種物理儲存單元上非連續 非順序的儲存結構,資料元素的邏輯順序是通過鍊錶中的指標鏈結次序實現的。鍊錶由一系列結點 鍊錶中每乙個元素稱為結點 組成,結點可以在執行時動態生成。每個結點包括兩個部分 乙個是儲存資料元素的資料域,另乙個是儲存下乙個結點位址的指標域。使用鍊錶結構可以克服陣列需要預先知道...

鍊錶的一些操作

判斷兩個鍊錶是否有交點 判斷兩個單鏈表是否相交,如果相交,給出相交的第乙個點 假設兩個鍊錶都不存在環 相交的煉表示意圖如下所示。兩個沒有環的鍊錶如果是相交於某一結點,如上圖所示,這個結點後面都是共有的。所以如果兩個鍊錶相交,那麼兩個鍊錶的尾結點的位址也是一樣的。程式實現時分別遍歷兩個單鏈表,直到尾結...