Hãy để tôi thử làm rõ thuật toán phát hiện chu kỳ được cung cấp tại http://en.wikipedia.org/wiki/Cycl_detection#Tortoir_and_hare bằng từ ngữ của riêng tôi.
Làm thế nào nó hoạt động
Chúng ta hãy có một con rùa và thỏ rừng (tên của con trỏ) chỉ vào đầu danh sách với một chu kỳ, như trong sơ đồ trên.
Chúng ta hãy đưa ra giả thuyết rằng nếu chúng ta di chuyển rùa 1 bước một lần và tăng 2 bước một lần, cuối cùng chúng sẽ gặp nhau tại một điểm. Chúng ta hãy chứng minh rằng trước hết giả thuyết này là đúng.
Hình minh họa một danh sách với một chu kỳ. Chu trình có độ dài n
và ban đầu chúng ta m
cách các chu kỳ. Ngoài ra, hãy nói rằng điểm gặp gỡ là k
bước ra khỏi chu kỳ bắt đầu và rùa và thỏ gặp nhau khi rùa đã thực hiện i
tổng số bước. (Hare sẽ thực hiện 2i
tổng số bước sau đó.).
2 điều kiện sau đây phải được giữ:
1) i = m + p * n + k
2) 2i = m + q * n + k
Người đầu tiên nói rằng rùa di chuyển i
các bước và trong các i
bước này, đầu tiên nó sẽ đến chu kỳ. Sau đó, nó đi qua p
thời gian chu kỳ cho một số số dương p
. Cuối cùng, nó đi qua k
nhiều nút hơn cho đến khi nó gặp thỏ rừng.
Một điều tương tự là đúng cho thỏ rừng. Nó di chuyển 2i
các bước và trong các 2i
bước này trước tiên nó sẽ đến chu kỳ. Sau đó, nó đi qua q
thời gian chu kỳ cho một số số dương q
. Cuối cùng, nó đi qua k
nhiều nút hơn cho đến khi gặp rùa.
Khi thỏ đi với tốc độ gấp đôi rùa, và thời gian là không đổi đối với cả hai khi chúng đến điểm hẹn.
Vì vậy, bằng cách sử dụng quan hệ tốc độ, thời gian và khoảng cách đơn giản,
2 ( m + p * n + k ) = m + q * n + k
=> 2m + 2pn + 2k = m + nq + k
=> m + k = ( q - 2p ) n
Trong số m, n, k, p, q, hai cái đầu tiên là thuộc tính của danh sách đã cho. Nếu chúng ta có thể chỉ ra rằng có ít nhất một tập hợp các giá trị cho k, q, p làm cho phương trình này đúng, chúng ta chỉ ra rằng giả thuyết này là đúng.
Một bộ giải pháp như sau:
p = 0
q = m
k = m n - m
Chúng tôi có thể xác minh rằng các giá trị này hoạt động như sau:
m + k = ( q - 2p ) n
=> m + mn - m = ( m - 2*0) n
=> mn = mn.
Đối với bộ này, i
là
i = m + p n + k
=> m + 0 * n + mn - m = mn.
Tất nhiên, bạn sẽ thấy rằng đây không nhất thiết là nhỏ nhất tôi có thể. Nói cách khác, rùa và thỏ có thể đã gặp nhau trước đó nhiều lần. Tuy nhiên, vì chúng tôi cho thấy rằng họ gặp nhau tại một số điểm ít nhất một lần chúng tôi có thể nói rằng giả thuyết này là chính xác. Vì vậy, họ sẽ phải gặp nhau nếu chúng ta di chuyển một trong số họ 1 bước, và một bước còn lại 2 bước một lần.
Bây giờ chúng ta có thể đi đến phần thứ hai của thuật toán đó là cách tìm phần đầu của chu kỳ.
Bắt đầu chu kỳ
Khi rùa và thỏ gặp nhau, chúng ta hãy đưa rùa trở lại đầu danh sách và giữ thỏ ở nơi chúng gặp nhau (cách k bước ra khỏi chu kỳ bắt đầu).
Giả thuyết là nếu chúng ta để chúng di chuyển với cùng tốc độ (1 bước cho cả hai), lần đầu tiên chúng gặp lại sẽ là chu kỳ bắt đầu.
Hãy chứng minh giả thuyết này.
Trước tiên hãy giả sử một số lời sấm cho chúng ta biết m là gì.
Sau đó, nếu chúng ta cho chúng di chuyển các bước m + k, rùa sẽ phải đến điểm mà chúng gặp ban đầu (k bước ra khỏi chu kỳ bắt đầu - xem trong hình).
Trước đây chúng tôi đã cho thấy rằng m + k = (q - 2p) n
.
Vì các bước m + k là bội số của độ dài chu kỳ n, nên, trong thời gian trung bình, sẽ đi qua chu kỳ (q-2p) và sẽ quay lại cùng một điểm (k bước ra khỏi chu kỳ bắt đầu).
Bây giờ, thay vì để chúng di chuyển các bước m + k, nếu chúng ta chỉ cho chúng di chuyển các bước m, rùa sẽ đến chu kỳ bắt đầu. Hare sẽ là k bước ngắn để hoàn thành các vòng quay (q-2p). Vì nó bắt đầu k bước trước chu kỳ bắt đầu, thỏ rừng sẽ phải đến chu kỳ bắt đầu.
Kết quả là, điều này giải thích rằng họ sẽ phải gặp nhau ở chu kỳ bắt đầu sau một số bước đầu tiên (lần đầu tiên vì rùa chỉ đến chu kỳ sau m bước và nó không bao giờ có thể thấy thỏ rừng đã ở trong đó chu kỳ).
Bây giờ chúng ta biết rằng số bước chúng ta cần để di chuyển chúng cho đến khi chúng gặp nhau hóa ra là khoảng cách từ đầu danh sách đến chu kỳ bắt đầu, m. Tất nhiên, thuật toán không cần biết m là gì. Nó sẽ chỉ di chuyển cả rùa và thỏ một bước cho đến khi chúng gặp nhau. Điểm gặp gỡ phải là bắt đầu chu kỳ và số bước phải là khoảng cách (m) đến chu kỳ bắt đầu. Giả sử chúng ta biết độ dài của danh sách, chúng ta cũng có thể, tính độ dài của chu kỳ trừ m từ chiều dài danh sách.