Floyd's Cycle Finding Algoritması (Tortoise and Hare)
Floyd'un Döngü Bulma Algoritması, bağlı listelerdeki döngüleri tespit etmek için kullanılan verimli bir algoritmadır. 'Kaplumbağa ve Tavşan' algoritması olarak da bilinir. Biri yavaş (kaplumbağa), diğeri hızlı (tavşan) hareket eden iki işaretçi kullanarak, döngü varsa bu iki işaretçinin mutlaka bir noktada buluşacağı prensibine dayanır.
Avantajlar
- Sabit bellek kullanımı (O(1) uzay karmaşıklığı)
- Doğrusal zaman karmaşıklığı (O(n))
- Döngünün başlangıç noktasını ve uzunluğunu tespit edebilir
- Uygulaması basittir ve minimum işaretçi kullanır
Dezavantajlar
- Yalnızca bağlı listeler veya işaretçi temelli veri yapıları için tasarlanmıştır
- Algoritma, durum makinesi veya otomat tabanlı algoritmalardan daha az sezgiseldir
- Hash tablosu kullanarak çözme yaklaşımından biraz daha yavaş olabilir
İnteraktif Demo
Floyd's Cycle Finding algoritmasını test edin. Aşağıdaki dizide her sayı, bir sonraki indeksi temsil eder (dizideki bir değer 3 ise, o pozisyonda 3. indekse bir bağlantı olduğunu gösterir). Döngü oluşturmak için, aynı indekse birden fazla bağlantı olmalıdır.
Her sayı, o indeksten bağlanan bir sonraki indeksi temsil eder. Sayılar 0 ile (dizi uzunluğu - 1) arasında olmalıdır.
Sonuç
Döngü tespit edilemedi.
Kod Örnekleri
Floyd's Cycle Finding algoritmasının farklı programlama dillerindeki implementasyonları.
1function floydCycleFinding(arr: T[]): { cycleExists: boolean; cycleStart?: number; cycleLength?: number } { 2 // Boş dizi kontrolü3 if (arr.length === 0) {4 return { cycleExists: false };5 }67 let tortoise = 0; // Yavaş hareket eden işaretçi (kaplumbağa)8 let hare = 0; // Hızlı hareket eden işaretçi (tavşan)9 10 // Faz 1: Döngünün varlığını tespit et11 do {12 // Kaplumbağa bir adım, tavşan iki adım ilerler13 tortoise = getNextIndex(arr, tortoise);14 hare = getNextIndex(arr, getNextIndex(arr, hare));15 16 // Dizi sınırlarını aşma kontrolü17 if (tortoise === -1 || hare === -1) {18 return { cycleExists: false };19 }20 21 } while (tortoise !== hare);22 23 // Buraya ulaşıldıysa, döngü var demektir24 25 // Faz 2: Döngünün başlangıç noktasını bul26 tortoise = 0;27 while (tortoise !== hare) {28 tortoise = getNextIndex(arr, tortoise);29 hare = getNextIndex(arr, hare);30 }31 32 // Döngünün uzunluğunu hesapla33 let cycleLength = 1;34 hare = getNextIndex(arr, tortoise);35 while (tortoise !== hare) {36 hare = getNextIndex(arr, hare);37 cycleLength++;38 }39 40 return {41 cycleExists: true,42 cycleStart: tortoise,43 cycleLength: cycleLength44 };45}
Algoritma Nasıl Çalışır?
Floyd'un Döngü Bulma Algoritması iki aşamada çalışır:
Faz 1: Döngünün Varlığını Tespit Etme
- İki işaretçi kullanılır: tortoise (kaplumbağa) ve hare (tavşan).
- Her adımda kaplumbağa bir adım, tavşan iki adım ilerler.
- Eğer döngü varsa, tavşan kaplumbağayı mutlaka yakalar (aynı noktada buluşurlar).
- Eğer tavşan listenin sonuna ulaşırsa (null/undefined), döngü yoktur.
Faz 2: Döngünün Başlangıç Noktasını Bulma
- Kaplumbağa başlangıç noktasına (0 indeksine) geri döner.
- Tavşan Faz 1'deki buluşma noktasında kalır.
- Şimdi her ikisi de aynı hızda (her adımda bir) ilerler.
- Buluştukları nokta, döngünün başlangıç noktasıdır.
Faz 3: Döngünün Uzunluğunu Hesaplama
- Döngünün başlangıç noktasından itibaren bir işaretçi ilerletilir.
- Başlangıç noktasına geri dönene kadar adımlar sayılır.
- Bu sayı, döngünün uzunluğunu verir.
Matematiksel Sezgi
Bu algoritmanın çalışmasının arkasındaki matematiksel sezgi şudur: Eğer kaplumbağa ve tavşan döngü içerisinde buluşursa, kaplumbağa 'k' adım atmışsa, tavşan '2k' adım atmıştır. Buluşma noktasından döngünün başlangıcına olan mesafe, başlangıç noktasından döngü başlangıcına olan mesafeye eşittir. Bu, döngünün başlangıcını bulmak için ikinci fazda iki işaretçinin neden aynı noktada buluştuğunu açıklar.