如何判斷兩個鍊錶是否有交點 鍊錶是否有環的判斷

2021-10-17 07:12:29 字數 3959 閱讀 4900

對於鍊錶是否存在環,有三個問題需要考慮:

1. 是否有環

2. 入環節點

3. 環的長度

第一種方法快慢指標法,也稱之為龜兔演算法,設定兩個指標,慢指標和快指標。最開始均指向鍊錶的頭節點,之後,快指標每次後移兩個節點,慢指標每次後移乙個節點。

1. 如果快指標指向空,則鍊錶無環

2. 若快指標和慢指標再次指向乙個相同節點,則證明鍊錶有環

入環節點:

記快慢指標首次在節點i處相遇,即二者均指向節點i。令慢指標指向鍊錶的頭節點h,

之後,慢指標和快指標同時移動,每次後移乙個指標,第乙個相遇的節點就是環的起點。

環的長度,兩種方法:

法1. 求入環節點時,在慢指標指向煉表頭節點、快指標指向節點i時,設定整型變數length = 0, 之後直至快慢指標相遇,二者每同時移動一次,lenght增加1。相遇後,length + 1 即環的長度。

法2. 在快慢指標指向相同的節點i時,設定 length = 0, 快指標仍每次後移兩個節點,慢指標每次後移乙個節點,快慢指標同時移動後, length增加1。 快慢指標再次相遇時,length即為環的長度。

對於思路可以進一步參閱:

第二種方法: brent's algorithm

例子:

python 實現**:

# python program to implement

# brent's cycle detection

# algorithm to detect cycle

# in a linked list.

# node class

class node:

# constructor to initialize

# the node object

def __init__(self, data):

self.data = data

self.next = none

class linkedlist:

# function to initialize head

def __init__(self):

self.head = none

# function to insert a new node

# at the beginning

def push(self, new_data):

new_node = node(new_data)

new_node.next = self.head

self.head = new_node

# utility function to prit

# the linked linkedlist

def printlist(self):

temp = self.head

while(temp):

print(temp.data, end=" ")

temp = temp.next

def detectcycle(self):

# if head is null

# then no loop

temp = self.head

if not (temp):

return false

first_p = temp

second_p = temp.next

power = 1

length = 1

# this loop runs till we

# find the loop. if there

# is no loop then second

# pointer ends at null

while (second_p and second_p != first_p):

# condition after which

# we will update the power

# and length as smallest

# power of two gives

# the start of cycle.

if (length == power):

# updating the power.

power *= 2

# updating the length

length = 0

first_p = second_p

second_p = second_p.next

length = length+1

# if it is null then no loop

if not (second_p):

return

# otherwise length stores

# actual length of loop.

# if needed, we can also

# print length of loop.

# print("length of loop is ")

# print (length)

# now set first_pointer

# to the beginning and

# second_pointer to

# beginning plus cycle

# length which is length.

first_p = second_p = self.head

while (length > 0):

second_p = second_p.next

length = length-1

# now move both pointers

# at same speed so that

# they meet at the

# beginning of loop.

while (second_p != first_p):

second_p = second_p.next

first_p = first_p.next

return first_p

# driver program for testing

llist = linkedlist()

llist.push(5)

llist.push(4)

llist.push(3)

llist.push(2)

llist.push(1)

# create a loop for testing

node = llist.head

while node.next:

node = node.next

node.next = llist.head.next

res = llist.detectcycle()

if(res.data):

print("loop found at ", end=' ')

print(res.data)

else:

print("no loop ")

第二種方法的優點在於:

1)在第乙個迴圈檢測是否存在環時, 也找到環的長度。

2)我們在每次迭代中只移動快指標,而避免移動第乙個指標,減少移動次數。

對於最開始提到的三個問題,對於入環的節點的思路 和 快慢指標方法中求環的長度的第一種處理思路 是共通的。

這裡是,已知環的長度,求入環節點,而快慢指標是已知環的節點求環的長度。 二者可以對比著看。

第三種做法:

遍歷鍊錶,將鍊錶的位址儲存在列表中,對於當前遍歷的節點,如果在列表中已經存在,則有環,且可以求出環的長度和入環節點。

如果鍊錶全部遍歷直至來鍊錶為空,則證明沒有環。

今天在看**的時候,偶然查到floyd's algorithm, 偶然看到這個問題。 10.10, 希望自己會更好。少無謂的道歉,多幾分滿意的感激。

如何判斷兩個鍊錶是否有交點

首先,兩個鍊錶如果有交點它應該是y型的。分別遍歷兩個鍊錶,如果尾節點位址相同,則有交點 分別遍歷兩個鍊錶,計算兩鍊錶長度,長的為a,短的為b,讓長的鍊錶先走a b步,然後兩個鍊錶儀器走,走到同一位址處為交點。把兩個鍊錶放到兩個陣列中遍歷,位址相同為交點。如何判斷單向鍊錶是否有環 遍歷放到鍊錶中,直到...

如何判斷兩個單向鍊錶是否有相交,並找出交點

判斷兩個鍊錶是否相交 假設兩個鍊錶都沒有環 1 判斷第乙個鍊錶的每個節點是否在第二個鍊錶中 2 把第二個鍊錶連線到第乙個後面,判斷得到的鍊錶是否有環,有環則相交 3 先遍歷第乙個鍊錶,記住最後乙個節點,再遍歷第二個鍊錶,得到最後乙個節點時和第乙個鍊錶的最後乙個節點做比較,如果相同,則相交 如何判斷乙...

如何判斷兩個單向鍊錶是否有相交,並找出交點

深信服一道筆試 如何判斷兩個單向鍊錶是否有相交,並找出交點。題比較簡單,單向鍊錶有交點意思就是交點後的節點都是一樣的了。node findnode node phead1,node phead2 while p1 next null while p2 next null if p1 p2 else ...