1 6帶環單鏈表

2022-07-13 16:48:12 字數 2737 閱讀 7561

定義乙個集合用來存放結點的引用,並將其初始化為空,從鍊錶的頭結點開始向後遍歷,每遍歷到乙個結點就判斷集合中是否有這個結點的引用,如果沒有,說明這個結點是第一次訪問,還沒有形成環,那麼將這個結點的引用新增到集合中去。如果在集合中找到了同樣的結點,那麼說明這個結點已經被訪問過了,於是就形成了環。這種方法的時間複雜度為o(n),空間複雜度也為o(n)。

定義兩個指標fast(快)與slow(慢),二者的初始值都指向煉表頭,指標slow每次前進一步,指標fast每次前進兩步,兩個指標同時向前移動,快指標每移動一次都要跟慢指標比較,如果快指標等於慢指標,就證明這個鍊錶是帶環的鍊錶。

如果單鏈表有環,那麼按照上述方法二的思路,當走得快的指標fast與走得慢的指標slow相遇時,slow 指標肯定沒有遍歷完鍊錶,而fast指標己經在環內迴圈了n圈 (n>=1)。如果slow 指標走了s步,則fast指標走了2s步,fast步數還等於s加上在環上多轉的n圈,假設環長為r,則滿足如下關係表示式:

2s = s +or

由此可以得到 : s=nr

設整個鍊錶長為l,入口環與相遇點距離為x,起點到環入口點的距離為a。則滿足如下關係表示式:

a+x=nr

a+x=(n-1)r+r=(n-l)r+l-a

a=(n-l)r+(l-ax)

(l-a-x)為相遇點到環入口點的距離,從煉表頭到環入口點的距離=(n-l)*環長+相遇點到環入口 點的長度,於是從煉表頭與相遇點分別設乙個指標,每次各走一步,兩個指標必定相遇,且相遇第一點為環入口點。將相遇點指標的前乙個節點的next域設成none即可解環。

# -*-coding:utf-8-*- 

"""@author : 圖南

@software: pycharm

@time : 2019/9/6 15:28

"""class node:

def __init__(self, data=none, next=none):

self.data = data

self.next = next

# 構造單鏈表

def con_link(s, k):

head = node()

cur = head

nums = list(map(int, s.split(' ')))

k = int(k)

for num in nums:

node = node(num)

cur.next = node

cur = node

tmp = head

if k != 0:

for i in range(k):

tmp = tmp.next

cur.next = tmp

return head

# 列印單鏈表(用到方法一中的思想)

def print_link(head):

if head is none or head.next is none:

return none

flag =

cur = head.next

while cur:

if cur not in flag:

print(cur.data, end=' ')

cur = cur.next

else:

print(cur.data, end=' ')

break

print()

# 判斷鍊錶中是否有環

def isloop(head):

if head is none or head.next is none:

return none

fast = head.next

slow = head.next

while true:

try:

fast = fast.next.next

slow = slow.next

except exception:

print("該鍊錶中沒有環!")

print_link(head)

return false, head

if fast == slow:

print("該鍊錶中有環!")

print_link(head)

return true, fast

# 查詢環的入點口,並解環

def findloopnode(head, fast):

cur = head.next

pre = none

while cur != fast:

pre = fast

cur = cur.next

fast = fast.next

print(cur.data)

# 解環並列印鍊錶

pre.next = none

print_link(head)

if __name__ == '__main__':

nums = input('鍊錶:')

# 輸入環的入口點,若為0則鍊錶中無環

k = input('環的入點口:')

head = con_link(nums, k)

f, fast = isloop(head)

if f:

findloopnode(head, fast)

帶環單鏈表

無環單鏈表

帶環單鏈表及單鏈表的相交

帶環單鏈表的概念 當單鏈表的尾指標指向了鍊錶上任一非尾結點時,即生成了乙個帶環單鏈表。問題一 判斷是否帶環 通過快慢指標實現判斷,注意快指標必須是兩步,慢指標必須是一步,否則可能跨過 問題二 求環的入口點 通過數學思想,方法是使用一指標指向開頭,一指標指向環中的相交點,每次各走一步,如此所得相交點即...

帶環單鏈表求中點

首先,對於乙個n節點的單鏈環,如果給定乙個開始節點n0,然後用a,b兩個指標,分別以1和2的步長遍歷,那麼在a環了多少圈 m a距離n0有乙個怎麼樣的偏移量 offset 的情況下,a,b會重合呢?即指向同乙個節點。讓我們跳過費神的數學推導證明什麼的,先給出答案吧。在a走完一圈之後,a,b會回到n0...

單鏈表帶環問題

判斷單鏈表是否帶環?若帶環,求環的長度?求環的入口點?1 2 3 4 5 6 7 8 9 不帶環 鍊錶遍歷一次,到最後的節點的下乙個節點會指向null,此時鍊錶不帶環。帶環 在判斷鍊錶是否帶環之前,應該先判斷鍊錶是否為空。空鍊錶肯定不帶環。只要鍊錶帶環,對鍊錶進行遍歷就會形成死迴圈,沒有出口。這是就...