Veri Yapıları ve Algoritmalar Ağaç Veri Yapısı (Tree Data Structure) Ağaç Veri Yapısı 1 Genel Bakış İkili Arama Ağacı / Binary Search Tree (BST) Düğüm İndis Ağaç Veri Yapısı bağlantısı yöntemi ile bağlantısı yöntemi ile 2 İkili Arama Ağacı İkili arama ağacı bir ikili ağaçtır. Bir D düğümünün Veri Yapısı ve C programlama dili ile örnek bir tanımı; struct BSTDgm { int veri; struct BSTDgm *solbag; struct BSTDgm *sagbag; }; Ağaç Veri Yapısı 3 İkili Arama Ağacı Ağaçta yapılan tüm işlemler, düğümde saklanan anahtar veri üzerinden yürütülür. Ağaçtaki her bir Di düğümündeki anahtar veri sol alt ağacındaki anahtar verilerden büyük ve sağ alt ağacındaki anahtar verilerden küçüktür(anahtar değerlerin eşit olma durumu varsa bu durum ağacın büyük veya küçük şartından biri ile birleştirilir ancak biz eşit durumunu anlatımda ele almayacağız). Ağaç Veri Yapısı 4 İkili Arama Ağacı Sizler de 2, 18, 20, 44 anahtar değere sahip düğümleri aşağıdaki ağaca ekleyiniz. Ağaç Veri Yapısı 5 İkili Arama Ağacı İkili arama ağacı düğümlerinde saklanan anahtar veriler kıyaslanabilir olmalıdır. İkili arama ağacının her alt ağacı da bir ikili arama ağacıdır. (bu sebeple özyinelemeli programlama tekniğine uygundur) İkili arama ağacında genel olarak yapılan işlemler; Yeni düğüm ekleme, Düğüm arama, Düğüm listeleme, Düğüm silme şeklinde olabilir. Ağaç Veri Yapısı 6 İkili Arama Ağacı 2, 18, 20, 44 ekleyiniz. Ağaç Veri Yapısı anahtar değere sahip düğümleri ağaca 7 İkili Arama Ağacı İkili bir arama ağacında, ekleme işlemi O(log2 n) zaman karmaşıklığı ile gerçekleştirilir. İkili bir arama ağacında, arama işlemi O(log2 n) zaman karmaşıklığı ile gerçekleştirilir. İkili bir arama ağacında, listeleme işlemi O(n) zaman karmaşıklığı ile gerçekleştirilir. İkili bir arama ağacında, silme işlemi O(log2 n) zaman karmaşıklığı ile gerçekleştirilir. İkili arama ağacına, yeni düğüm daima yaprak düğüm olarak eklenmektedir. İkili arama ağaçları üzerinde yapılan işlemlere ait algoritmaların sözde kodu izleyen sunum sayfalarında verilmiştir. Ağaç Veri Yapısı 8 İkili Arama Ağacı İkili arama ağacına düğüm ekleme algoritması sözde kodu: /*Ağaçtaki işlemlerde düğümde saklanan anahtar veri üzerinden işlemler yapılır */ DugumEkle(BSTDgm** Kök, YeniVeri) { If (Kök NULL değere eşit ise) /* Ağaçta, özyinelemeli olarak bir nevi arama yapılarak Yeni düğümün bağlanması gereken yaprak düğüme ulaşıldı ve Yeni düğüm o yaprak düğüme bağlandı */ YeniVeri için Yenidüğüm oluştur Kök = Yenidüğüm else if (YeniVeri < Kök ) then /*Ağacın sol alt ağacındaki düğüm Kök oldu ve fonksiyon kendini çağırdı*/ DugumEkle(Kök sol alt ağaç adresi, YeniVeri) ; else /* Ağacın sağ alt ağacındaki düğüm Kök oldu ve fonksiyon kendini çağırdı*/ DugumEkle(Kök sağ alt ağaç adresi, YeniVeri) ; } Ağaç Veri Yapısı 9 İkili Arama Ağacı İkili arama ağacına düğüm ekleme işlemi için programlama dili ile yazılmış bir fonksiyonun kodu: Ağaç Veri Yapısı C 10 İkili Arama Ağacı İkili arama ağacında arama algoritması sözde kodu: /*Ağaçtaki işlemlerde düğümde saklanan anahtar veri üzerinden işlemler yapılır */ BSTDgm* Ara(BSTDgm** Kök, AraVeri) {/* Ağaçta AraVeri yoksa ağacın düğüm sayısına bağlı olarak if (Kök NULL değere eşit değil ise) belli bir özyinelemeden sonra Kök değer NULL olacaktır */ If (Kök eşit Araveri ise) KökAdresi döndür. /* Ağaçta, özyinelemeli arama yapılarak düğüme ulaşılmıştır, o anki kök düğüm ağaçta Araveri ile aynı anahtar değere sahip bir düğümdür.*/ else if (AraVeri < Kök ) then /*Ağacın sol alt ağacındaki düğüm Kök oldu ve fonksiyon kendini çağırdı*/ Ara(Kök sol alt ağaç adresi, AraVeri) ; else /* Ağacın sağ alt ağacındaki düğüm Kök oldu ve fonksiyon kendini çağırdı*/ Ara(Kök sağ alt ağaç adresi, AraVeri) ; } else NULL döndür } } Veri Yapısı Ağaç 11 İkili Arama Ağacı İkili arama ağacında dolaşma algoritma sözde kodları: /*Ağaçtaki işlemlerde düğümde saklanan anahtar veri üzerinden işlemler yapılır */ BaştaKök(BSTDgm* Kök) { if (Kök NULL değere eşit değil ise){ Kök Düğümdeki Veriyi göster /* Ağacın bir düğümü dolaşılmış oldu */ /* Ağacın sol alt ağacındaki düğüm Kök oldu ve fonksiyon kendini çağırdı */ BaştaKök(Kök sol alt ağaç adresi) ; /* Ağacın sağ alt ağacındaki düğüm Kök oldu ve fonksiyon kendini çağırdı */ BaştaKök(Kök sağ alt ağaç adresi) ; } } Ağaç Veri Yapısı 12 İkili Arama Ağacı İkili arama ağacında dolaşma algoritma sözde kodları: /*Ağaçtaki işlemlerde düğümde saklanan anahtar veri üzerinden işlemler yapılır */ OrtaKök(BSTDgm* Kök) { if (Kök NULL değere eşit değil ise){ /* Ağacın sol alt ağacındaki düğüm Kök oldu ve fonksiyon kendini çağırdı */ OrtaKök(Kök sol alt ağaç adresi) ; Kök Düğümdeki Veriyi göster /* Ağacın bir düğümü dolaşılmış oldu */ /* Ağacın sağ alt ağacındaki düğüm Kök oldu ve fonksiyon kendini çağırdı */ OrtaKök(Kök sağ alt ağaç adresi) ; } } Ağaç Veri Yapısı 13 İkili Arama Ağacı İkili arama ağacında dolaşma algoritma sözde kodları: /*Ağaçtaki işlemlerde düğümde saklanan anahtar veri üzerinden işlemler yapılır */ SonraKök(BSTDgm *Kök) { if (Kök NULL değere eşit değil ise){ /* Ağacın sol alt ağacındaki düğüm Kök oldu ve fonksiyon kendini çağırdı */ SonraKök(Kök sol alt ağaç adresi) ; /* Ağacın sağ alt ağacındaki düğüm Kök oldu ve fonksiyon kendini çağırdı */ SonraKök(Kök sağ alt ağaç adresi) ; Kök Düğümdeki Veriyi göster /* Ağacın bir düğümü dolaşılmış oldu */ } } Ağaç Veri Yapısı 14 İkili Arama Ağacı İkili arama ağacından düğüm silme; İkili arama ağacından düğüm silme algoritmasında silinecek düğüm çocuk sayısı bakımından 3 farklı şekilde olabilir bunlar; 1- Silinecek düğüm yaprak düğümdür. 2- Silinecek düğüm tek çocuğu olan bir düğümdür. 3- Silinecek düğüm iki çocuğu olan bir düğümdür. Ağaç Veri Yapısı 15 İkili Arama Ağacı 1- Silinecek düğüm yaprak düğümdür, yani hiç çocuğu yoktur. Bu durumda silinecek düğümü gösteren aile düğümün, ilgili bağ bilgisine NULL değeri atanır ve silinecek düğüme ait bellek alanı serbest bırakılır. 1 anahtar verisine sahip düğüm silme adımları aşağıdadır. Ağaç Veri Yapısı 16 İkili Arama Ağacı 2- Silinecek düğüm tek çocuğu olan bir düğümdür, yani sağ yada sol bağ bilgisi bulunan bir düğümdür. Bu durumda silinecek düğümü gösteren aile düğümün ilgili bağ bilgisi alanına, silinecek düğümün gösterdiği çocuk düğümün bağ bilgisi atanır ve silinecek düğümün bellek alanı serbest bırakılır. 12 anahtar verisine sahip düğüm silme adımları aşağıdadır. Ağaç Veri Yapısı 17 İkili Arama Ağacı 3- Silinecek düğüm iki çocuğu olan bir düğümdür, yani sağ ve sol bağ bilgisi bulunan bir düğümdür. Bu durumda silinecek düğümün anahtar veri alanına sağ alt ağacının en küçük düğümünün anahtar verisi (yada sol alt ağacının en büyük düğümünün anahtar verisi) taşınır ve anahtar verisi taşınan düğümün bellek alanı serbest bırakılır. 3 anahtar verisine sahip düğüm silme adımları aşağıdadır. Ağaç Veri Yapısı 18 İkili Arama Ağacı İkili arama ağacında düğüm silme algoritması sözde kodu: /*Ağaçtaki işlemlerde düğümde saklanan anahtar veri üzerinden işlemler yapılır */ BSTDgm* DüğümSil(BSTDgm* Kök, SilVeri) { if (Kök NULL değere eşit ise) KökAdresi döndür if (SilVeri < Kök ) then /*Ağacın sol alt ağacındaki düğüm Kök oldu ve fonksiyon kendini çağırdı*/ Kök sol alt ağaç adres = DüğümSil(Kök sol alt ağaç adresi, SilVeri) else if (SilVeri > Kök ) then /*Ağacın sağ alt ağacındaki düğüm Kök oldu ve fonksiyon kendini çağırdı*/ Kök sağ alt ağaç adres = DüğümSil(Kök sağ alt ağaç adresi, SilVeri) } else{ if (Kök sol alt ağaç adresi NULL değere eşit ise) then Kökün sağ bağındaki düğümü döndür else if (Kök sağ alt ağaç adresi NULL değere eşit ise) then Kökün sol bağındaki düğümü döndür Kökün anahtar veri alanına, sağ alt ağacının en küçük anahtar değerli düğümün anahtar verisini taşı Kök sağ bağ = DüğümSil(Kök sağ alt ağaç adresi, en küçük anahtar değerli düğümün anahtar verisi ) } KökAdresi döndür } Veri Yapısı Ağaç 19 İkili Arama Ağacı İkili arama ağacının dizi veri yapısı ile temsili Şu ana kadar yapılan ikili Arama ağacının düğüm bağlantısı ile ayrık bellek alanlarında temsilinin yanı sıra dizi veri yapısı ile de ikili arama ağacı temsili yapılabilir. Bunun için düğüm bağlantısı ile ikili arama ağacında yapılan işlemlerin bir dizi üzerinde de yapılması gerekir. Aşağıda görsel temsili bulunan n elemanlı tamsayı veri tipinde D[n] dizisi kullandığımızı varsayalım; İlk veri alanı yani 0 indisli alan kök olarak ifade edilir. Ağaç Veri Yapısı 20 İkili Arama Ağacı İkili arama ağacının dizi veri yapısı ile temsili i=0 kök=D[i] D[i] sol indisi = Köksol indisi = 2 * i + 1 = 2 * 0 + 1 = 1 D[i] sağ indisi = Köksağ indisi = 2 * i + 2 = 2 * 0 + 2 = 2 olacaktır Ağaç Veri Yapısı 21 İkili Arama Ağacı Aşağıda verilen İkili arama ağacının, dizi veri yapısı ile temsili altında verilmiştir. Verilen indis hesaplama yöntemi ile indisleri kullanarak arama işlemi yapınız. Ağaç Veri Yapısı 22 İkili Arama Ağacı Ancak bu örnekte ağaçların dizi temsili için ideal bir durum görülmektedir ve bu durum önemli bir avantaj sağlamıştır. Bu ideal durum ağacın dengeli olmasının yanında Complete Binary Tree ağacının bir özelliğine sahip olmasıdır; Complete Binary Tree ; İkili ağaçtır. Her yeni düğüm, düzeye soldan sağa doğru eklenir ve bir düzeydeki düğüm sayısı tamamlanmadan bir sonraki düzeye inilmez ve bir düzeyde yeni düğümler için boş alanlar ağacın daima sağ tarafındadır. Ağaç Veri Yapısı 23 İkili Arama Ağacı Full Binary Tree; Yapraklar hariç her bir düğümün iki çocuğu olan ikili ağaçtır, tüm yaprakları aynı derinliktedir. Bu iki ağaç türünün ikili arama ağacı olma özelliklerini gerektirmediği görülmelidir. Ağaç Veri Yapısı 24 İkili Arama Ağacı Eğer ağaç Full Binary Tree veya Complete Binary Tree gibi arada düğüm boşlukları olmayan bir ikili arama ağacı ise ağacın dizi veri yapısı ile temsili avantajlı bir durum olacaktır. Bu avantajlar sizce nedir ? Aksi durumda dezavantajları nelerdir? Ağaç Veri Yapısı 25 İkili Arama Ağacı C programlama dili kullanarak düğüm bağlantısı ile örnek uygulamalar İkili arama ağacını oluşturma/ekleme ve ağacı dolaşma yöntemleri uygulaması. İkili arama ağacında arama uygulaması. İkili arama ağacından düğüm silme uygulaması. Ağaç Veri Yapısı 26 İkili Arama Ağacı Çalışma soruları 1 Menu 1- Dosyadan ikili arama ağacı oluştur(kelime frekansı düğümde saklansın) 2- Ağaçta kelime arama 3- Kelime frekanslarını listele 4- Kelimeleri alfabetik sıralı şekilde dosyaya yaz 5- Ağaçtaki toplam düğüm sayısını görüntüle 6- çıkış Seçiminiz(«1/2/3/4/5/6 »)_ Açıklaması diğer sunu sayfasında verilmiştir. Ağaç Veri Yapısı 27 İkili Arama Ağacı Çalışma soruları 1 Doğal dil ile yazılmış bir metin dosyasından; kelimeleri birer birer okuyup ikili arama ağacına ekleyerek(uygulamada sadece bir tane ikili arama ağacı olacak) bir ikili arama ağacı oluşturunuz düğümlerde kelimelerin metin içinde kaç defa bulunduğu bilgisi saklanacaktır. Oluşturulan bu ikili arama ağacında, klavyeden gireceğiniz bir kelimeyi arayınız ve bulunur ise ekrana frekansını görüntüleyiniz. Oluşturulan bu ağaçtaki tüm kelimeleri ekrana; kelime frekansı anne 10 an 20 ……… ….. şeklinde listeleyiniz. Ekrana yapılan listeleme işlemini aynı şekilde bir dosyaya yazdırınız. Ağaç Veri Yapısı 28 İkili Arama Ağacı Çalışma soruları 2 Çalışma sorusu 1’ de tüm kelimeler için bir tek ikili arama ağacı oluşturulmanız istenmiştir. Bu soruda, menüde belirtilen aynı işlemleri her bir kelimenin baş harfine göre 256 (genişletilmiş ASCII tablosu karakterlerinin her biri için bir ağaç olacak şekilde [0255]) farklı ikili arama ağacı(orman) oluşturulacaktır. Uygulamayı bir de bu şekilde tasarlayarak kodlayınız. Örneğin dosyada : «ali eve döndü ama ayşe henüz burada» şeklinde bir metin yazılmış ise; «a» ikili arama ağacına «ali»,»ama»,»ayşe» «b» ikili arama ağacına «burada» «d» ikili arama ağacına «döndü» «e» ikili arama ağacına «eve» «h» ikili arama ağacına «henüz» İkili arama ağaçlarına eklenecektir. Ağaç Veri Yapısı 29 İkili Arama Ağacı Çalışma soruları 3 Örnek olarak kodları sizlere verilen düğüm bağlantısı ile ikili arama ağacı uygulamalarını, indis bağlantısı ile ikili arama ağacı uygulamaları haline dönüştürebilirsiniz. Ağaç Veri Yapısı 30 Veri Yapıları ve Algoritmalar Kaynakça Dr. Rifat ÇÖLKESEN, Veri Yapıları ve Algoritmalar, Papatya yayıncılık, 2014, 10. basım.(Ders kitabı) http://www.algolist.net/Data_structures/Binary_search_tr ee Ağaç Veri Yapısı Dr. Öğr. Üyesi Aydın CARUS - 2020 31