判斷一個連結串列是否存在環(Python)
阿新 • • 發佈:2019-02-13
判斷一個連結串列是否存在環:例如n1->n2->n3->n4->n5->n6->n2就是一個有環的連結串列,環的開始結點是n6。
有的部落格說的一種方法:遍歷連結串列,將遍歷過的結點放在一個字典中,如果一個結點已經存在字典中,說明有環。
個人認為這種方法不可行,因為如果連結串列中如果有重複的元素,但是重複的元素的地址是不一樣的,此時並沒有形成環。所以這種判斷環的方法不可行。
下面是正確的解法:用快慢指標的方法。時間複雜度O(n),空間複雜度O(1)。
設定p1為慢指標,p2為快指標,兩者初始時都指向連結串列的頭結點 ,慢指標p1每次前進1步,快指標p2每次前進2步。如果連結串列存在環,則快指標p2肯定先進入環,慢指標p1後進入環,兩個指標必定會相遇。如果不存在環,則快指標會先行到達連結串列的尾部變為None。
以下是程式:
class LNode: def __init__(self, elem): self.elem = elem self.pnext = None def exitLoop(LList): p1 = p2 = LList while p2 and p2.pnext: #當連結串列為空或者只有一個結點時,就不執行迴圈體裡的程式,返回False p1 = p1.pnext p2 = p2.pnext.pnext if p1 == p2: return True return False if __name__=="__main__": LList = LNode(1) p1 = LNode(2) p2 = LNode(3) p3 = LNode(4) p4 = LNode(5) p5 = LNode(6) LList.pnext = p1 p1.pnext = p2 p2.pnext = p3 p3.pnext = p4 p4.pnext = p5 p5.pnext = p2 print(exitLoop(LList))