1. 程式人生 > >如何尋找歐拉回路、尤拉通路(套圈法)

如何尋找歐拉回路、尤拉通路(套圈法)

傳說中的套圈法。

演算法思想的樸素表達

對於尤拉圖,從一個節點出發,隨便往下走(走過之後需要標記一下,下次就不要來了),必然也在這個節點終止(因為除了起始節點,其他節點的度數都是偶數,只要能進去就能出來)。這樣就構成了一個圈,但因為是隨便走的,所以可能會有些邊還沒走過就回來了。我們就從終止節點逆著往前查詢,直到找到第一個分叉路口,然後從這個節點出發繼續上面的步驟,肯定也是可以找到一條回到這個點的路徑的,這時我們把兩個圈連在一起。當你把所有的圈都找出來後,整個歐拉回路的尋找就完成了。

尋找歐拉回路時,起始節點是可以任意選擇的。如果是有基度頂點要尋找尤拉通路,則從基度頂點出發就好了,上述步驟依然有效。

演算法思想的書面表達

一個解決此類問題基本的想法是從某個節點開始,然後查出一個從這個點出發回到這個點的環路徑。現在,環已經建立,這種方法保證每個點都被遍歷.如果有某個 點的邊沒有被遍歷就讓這個點為起點,這條邊為起始邊,把它和當前的環銜接上。這樣直至所有的邊都被遍歷。這樣,整個圖就被連線到一起了。

更正式的說,要找出尤拉路徑,就要迴圈地找出出發點。按以下步驟:

任取一個起點,開始下面的步驟
如果該點沒有相連的點,就將該點加進路徑中然後返回。
如果該點有相連的點,就列一張相連點的表然後遍歷它們直到該點沒有相連的點。(遍歷一個點,刪除一個點)
處理當前的點,刪除和這個點相連的邊, 在它相鄰的點上重複上面的步驟,把當前這個點加入路徑中.
下面是虛擬碼:

# circuit is a global array
find_euler_circuit
circuitpos = 0
find_circuit(node 1)

# nextnode and visited is a local array
# the path will be found in reverse order
find_circuit(node i)

if node i has no neighbors then
circuit(circuitpos) = node i
circuitpos = circuitpos + 1
else
while (node i has neighbors)
pick a random neighbor node j of node i
delete_edges (node j, node i)
find_circuit (node j)
circuit(circuitpos) = node i
circuitpos = circuitpos + 1
要找尤拉路徑, 只要簡單的找出一個度為奇數的節點,然後呼叫 find_circuit 就可以了.

一點點程式碼(pku 2337裡面截過來的,具體請看http://blog.csdn.net/logic_nut/archive/2009/08/22/4473174.aspx)