Evet, bu sıkıştırmayı zamanında yapabilirsiniz, ancak bu kolay değildir :) Önce bazı gözlemler yaparız ve sonra algoritmayı sunarız. Ağacın başlangıçta sıkıştırılmadığını varsayarız - bu gerçekten gerekli değildir, ancak analizi kolaylaştırır.O(nlogn)
İlk olarak, 'yapısal eşitliği' tümevarımsal olarak nitelendiriyoruz. Let ve T ' , iki (alt) ağaç olabilir. Eğer T ve T ' (da hiç tepe noktalarına sahip olan) boş ağaç hem de, yapısal eşdeğerdir. Eğer T ve T ' hem boş değil ağaçlar, bu durumda onlar da sol çocukları yapısal olarak eşdeğerdir ve onların sağ çocukları yapısal olarak eşdeğerdir IFF yapısal olarak eşdeğerdir. 'Yapısal eşdeğerlik', bu tanımlar üzerindeki minimum sabit noktadır.TT′TT′TT′
Örneğin, herhangi iki yaprak düğümü yapısal olarak eşdeğerdir, çünkü her ikisi de yapısal olarak eşdeğer olan her iki çocuğu olarak da boş ağaçlara sahiptir.
'Sol çocukları yapısal olarak eşdeğerdir ve sağ çocukları da' demek oldukça can sıkıcı olduğu için, sık sık 'çocukları yapısal olarak eşdeğerdir' diyeceğiz ve aynı şeyi düşüneceğiz. Ayrıca, 'bu tepe noktasına dayanan alt ağaç' demek istediğimizde bazen 'bu tepe noktasını' söylediğimizi unutmayın.
Yukarıdaki tanım bize derhal sıkıştırmanın nasıl yapılacağına dair bir ipucu verir: tüm alt ağaçların derinliği en fazla olan yapısal eşdeğerliğini bilirsek, alt ağaçların yapısal eşdeğerliğini d + 1 derinliği ile kolayca hesaplayabiliriz . O ( n 2 ) çalışma süresinden kaçınmak için bu hesaplamayı akıllı bir şekilde yapmak zorundayız .dd+1O(n2)
Algoritma, yürütülmesi sırasında her tepe noktasına tanımlayıcılar atayacaktır. Bir tanımlayıcı kümesindeki bir sayıdır . Tanımlayıcılar benzersizdir ve asla değişmez: bu nedenle algoritmanın başlangıcında bazı (global) değişkenleri 1 olarak ayarladığımızı ve bazı tepe noktalarına her tanımlayıcı atadığımızda, bu değişkenin geçerli değerini tepe noktasına ve artışa atarız bu değişkenin değeri.{1,2,3,…,n}
İlk olarak giriş ağacını , ebeveynlerine bir işaretçi ile birlikte eşit derinliğe sahip köşeler içeren (en fazla ) listeye dönüştürüyoruz . Bu kolayca O ( n ) zamanda yapılabilir.nO(n)
Öncelikle tüm yaprakları (bu yaprakları listede 0 derinlik köşeleriyle bulabiliriz) tek bir tepe noktasına sıkıştırırız. Bu tepe noktasına bir tanımlayıcı atarız. İki köşenin sıkıştırılması, her bir tepe noktasının üst öğesini diğer tepe noktasına işaret edecek şekilde yönlendirerek yapılır.
İki gözlem yapıyoruz: ilk olarak, herhangi bir tepe noktasının kesinlikle daha küçük derinliğe sahip çocukları var ve ikincisi, den daha küçük tüm derinliklerde sıkıştırma gerçekleştirdiysek (ve onlara tanımlayıcılar verdiysek ), d derinliğinin iki köşesi yapısal olarak eşdeğerdir ve çocuklarının tanımlayıcıları çakıştığında sıkıştırılabilir. Bu son gözlem aşağıdaki argümandan kaynaklanmaktadır: iki köşesi, çocukları yapısal olarak eşdeğer olduğunda yapısal olarak eşdeğerdir ve sıkıştırmadan sonra, işaretçileri aynı çocukları işaret ettiği anlamına gelir, bu da çocuklarının tanımlayıcılarının eşit olduğu anlamına gelir.dd
Küçük derinlikten büyük derinliğe kadar eşit derinliğe sahip düğümleri olan tüm listeleri tekrarlıyoruz. Her seviye için, her bir çiftin o seviyedeki bazı tepe noktalarının çocuklarının tanımlayıcılarına karşılık geldiği bir tamsayı çiftleri listesi oluştururuz. Karşılık gelen tamsayı çiftleri eşit olduğu takdirde, bu seviyedeki iki köşenin yapısal olarak eşdeğer olduğuna sahibiz. Sözcük bilgisi düzenini kullanarak bunları sıralayabilir ve eşit olan tamsayı çiftleri kümesini elde edebiliriz. Bu setleri yukarıdaki gibi tek köşelere sıkıştırır ve tanımlayıcıları veririz.
Yukarıdaki gözlemler bu yaklaşımın işe yaradığını ve sıkıştırılmış ağaçla sonuçlandığını kanıtlamaktadır. Toplam çalışma süresi artı oluşturduğumuz listeleri sıralamak için gereken süredir. Oluşturduğumuz tamsayı çiftlerinin toplam sayısı n olduğundan bu, toplam çalışma süresinin gerektiği gibi O ( n log n ) olduğunu gösterir. Prosedürün sonunda kaç düğüm kaldığımızı saymak önemsizdir (sadece kaç tanımlayıcıyı dağıttığımıza bakın).O(n)nO(nlogn)