27.12.2013 Veri Yapıları Ağaçlar Dr. Sinan TUNCEL Ağaçlar genel bilgi • • • Ağaçlar, fizikçi Gustava Kirşof tarafından 1847’de kablo ağlarındaki elektrik akışını formülize etmek için kullanılmıştır. Kirşof yasaları olarak adlandırılan denklemlerin tamamı bağımsız olmadığından Kirşof ağaçları kullanarak bu denklemlerin hangilerinin bağımsız olduğunu belirlemiştir. Ağaç terimi, bu çalışmalardan on yıl sonra İngiliz matematikçi Arthur Cayley tarafından verilmiştir. Cayley matematik içerisindeki bir problemi incelemek için ağaçlar üzerine odaklanarak çalışmalar gerçekleştirmiştir. Cayley kimyadaki izomerleri ağaçları kullanarak incelemiş ve teoriyi uygulamaya taşımına becerisini göstermiştir. 1 27.12.2013 Ağaçlar genel bilgi • • • • Ağaçlar, verilerin birbirine sanki bir ağaç yapısı oluşturuyormuş gibi sanal olarak bağlanmasıyla elde edilen bir veri modelidir. Ağaç veri modeli daha fazla belek alanına gereksinim duyar. Bağlı listeler, yığınlar ve kuyruklar doğrusal (linear) veri yapılarıdır. Ağaçlar ise doğrusal olmayan belirli niteliklere sahip iki boyutlu veri yapılarıdır. İçerisinde çevrim (cycle) bulundurmayan bağlantılı grafların özel bir türüne ağaç adı verilir. Ağaçlar bir çok nedenden dolayı graf teorisi içerisinde önemli bir yere sahiptir. Ayrıca, ağaçlar graf teorisinin birçok uygulamasında ön plana çıkmaktadır. Dr.Sinan TUNCEL 3 Nerelerde Kullanılır Ağaç veri yapısı, günlük yaşamda da karşılaştığımız bir yapıdır. • Bir insanın/bitkinin soy ağacı • hiyerarşik bir yönetimdeki ilişkiler • şirketlerdeki organizasyon şeması ağaç veri yapısı kullanılarak kolayca grafiksel olarak tanımlanabilir. 2 27.12.2013 Nerelerde Kullanılır Ağaç veri yapısı, bilgisayar bilimlerinde önemli yer tutar. Yazılım dünyasında birçok yerde programcının karşısına çıkar. • • • • • • • • • • Arama Sıralama Söz dizim Veri sıkıştırma Çözümleme (syntax analysis) Kod optimizasyonu (code optimization) Derleyici gerçekleştirimindeki ara süreçler Hiyerarşik veritabanı İşletim sistemlerinin dosya sistemi. Oyunların olası hamleleri. Nerelerde Kullanılır 3 27.12.2013 Nerelerde Kullanılır Dosya Sistemi /ymt kodlar kitaplar ymt219 ymt112 1.pdf 2.pdf 1.pdf ... dersler 2010-2011 eski a.java b.java ymt219 ymt217 1.ppt 1.doc ymt215 ... 1.Pdf 7 Faydaları Esneklik : Tek bir amaç için en iyi çözüm ağaç yapısı olmasa da, çoklu çözümler için ağaç yapısının esnekliği bu yapının avantajı olarak sayılabilir. Etkili Arama: Arama sırasında ağacın bazı dalları budanarak arama yapılması performans artışı sağlar ve bu da verimliliği arttırır. Ağaç yapısı genellikle bilginin istenilen bölümüne konumlanmak için genellikle filtreleme aracı olarak kullanılır. Doğal Temsil: Bilgiyi temsil etmenin doğal bir yoludur. Ağaç yapısı bir uygulamayı bazen daha kolay uygulanabilir bir hale dönüştürür. 4 27.12.2013 Ağaç Üzerinde Bazı Tanımlar 2 Dügüm (node) : Agacın her bir elemanına dügüm adı verilir. Örnekler : A, B, C. Kök Derinlik 1 A B C Ara Düğüm Yaprak Düğüm 3 D 4 E Yaprak Düğüm F G 7 düğümlü ağaç Kök (root) :Agacın en üstteki dügümüne kök (root) adı verilir Düzey 0'daki tek dügüm. Çocuk (child) : : Bir düğüme doğrudan bağlı (sol ve sag bagı aracılıgı ile baglandıgı dügümler) olan düğümlere o düğümün çocukları denir. B ve C, A'nın çocuklarıdır. 9 Ağaç Üzerinde Bazı Tanımlar Kardeş Düğüm (sibling, brother) : Aynı düğüme bağlı (Aynı parent'a sahip) düğümlere denir. Örnekler : B ile C kardestir. D ile E kardestir. H ile I kardestir. Aile (Parent) : Düğümlerin doğrudan bağlı olduğu düğüme denir (Bir dügüm, sag ve sol bagları ile baglandıgı dügümlerin parent'ıdır) A dügümü, B ve C dügümlerinin parent'ıdır. Ata: Aile düğümünün üstündeki düğüme ata denir. Orman: Ağaçlar kümesi Yol: Bir düğümden başka bir düğüme gidebilmek için üzerinden geçilmesi gereken düğümlerin listesi. Derece: Bir düğümden alt hiyerarşiye yapılan bağlantıların sayısıdır. Düzey / Derinlik (depth) : Kök ile düğüm arasındaki yolun üzerinde bulunan düğümlerin sayısıdır. Bir düğümün kök dügümden olan uzaklıgıdır. Örnek : D düğümünün düzeyi veya derinliği 2'dir. Ağacın derinligi (depth of tree) : En derindeki yaprağın derinliği veya yüksekligi (height). Yükseklik: Bir düğümün kendi silsilesindeki en uzak mesafedeki yaprak düğüme olan düzey sayısı 5 27.12.2013 Ağaç Üzerinde Bazı Tanımlar Altağaç: Ağacın herhangi bir dalı Yaprak (leaf) : Sol ve sag bagı bos olan düğümlere yaprak adı verilir. Örnekler : D,G,H,I. Ancestor (üst dügüm) : Bir düğümün parent'ı birinci ancestor'ıdır. Parent'ın parent'ı (recursion) ikinci ancestor'ıdır. Kök, kendi hariç tüm dügümlerin ancestor'ıdır. Descendant (alt dügüm) : Bir düğümün iki çocuğu birinci alt düğümüdür. Onların çocukları da ikinci alt düğümüdür. N tane düğümden oluşan bir ağacın kenar sayısı N-1 tanedir. Ağaçtaki iki düğüm arasında en fazla 1 yol olabilir. Dr.Sinan TUNCEL 11 Ağaç Üzerinde Bazı Tanımlar Kök A B C D E F G Tanım kök B D Çocuk/Derece 2 0 0 Kardeş 1 2 3 Düzey 1 2 3 Aile yok kök C Ata yok yok Kök Yol A A, B A,C,D Derinlik 1 2 3 Yükseklik 4 3 2 12 6 27.12.2013 Ağaç Üzerinde Bazı Tanımlar Dr.Sinan TUNCEL 13 Ağaçlar • Ağaç yapıları ikili veya çoklu bağlı listeler ile gerçekleştirilebilir. • Ağaçlardaki düğümlerden iki veya daha fazla bağ çıkabilir. İkili ağaçlar (binary trees), düğümlerinde en fazla iki bağ içeren (0,1 veya 2) ağaçlardır. Ağaç veri modelinde, bir kök işaretçisi, sonlu sayıda düğümleri ve onları birbirine bağlayan dalları vardır. Veri ağacın düğümlerinde tutulur. Dallarda ise geçiş koşulları vardır. Her ağacın bir kök işaretçisi vardır. Ağaca henüz bir düğüm eklenmemiş ise ağaç boştur ve kök işaretçisi NULL değerini gösterir. Ağaç bu kök etrafında dallanır ve genişler. • Dr.Sinan TUNCEL 14 7 27.12.2013 Ağaç veri modelinin uygulanması • • • Sekil de görülen ağacın düğümlerindeki bilgiler sayılardan oluşmuştur. Her düğümdeki sol ve sağ bağlar yardımı ile diğer düğümlere ulaşılır. Sol (leftptr) ve sag (rightptr) baglar bos ("NULL" = "/" = "\") da olabilir. Düğüm yapıları değişik türlerde bilgiler içeren veya birden fazla bilgi içeren ağaçlar da olabilir. veri yapılarındaki ağaçlar kökü yukarıda yaprakları aşağıda olacak şekilde çizilirler. Level Kök Node 1 1 Kök 2 4 5 Yaprak 8 2 3 Yaprak Node 6 9 Yaprak 3 7 10 4 11 12 13 Yaprak Yaprak Yaprak 5 (Binary Tree) Dr.Sinan TUNCEL 15 Ağaç (Tree) Arama ve sıralama işlemleri için kullanılan İkili Arama Ağacı (BST: Binary Search Tree) gibi özel ağaç türleri de vardır. Ağaç yapıları ikili veya çoklu bağlı listeler ile gerçekleştirilebilir. bağ1 veri veri bağ2 veri 8 27.12.2013 Ağaçlar Ağaç tanımı özyinelemelidir: Bir ağaç iki şekilde olabilir: a. Boş düğüm kümesi, veya b. Kök ismi verilen bir düğüm ve 0 veya daha fazla alt-ağacı olan yapı. Ağaç veri yapısını gerçekleştirmek için 2 yol vardır. Bağlantılı liste kullanmak Dizi kullanmak 17 Ağaç Gerçekleştirimi Her bir bağlantı için birer bağlantı bilgisi tutulur. A B C E • D F Problem: Bir sonraki elemanın çocuk sayısını bilmiyoruz. 18 9 27.12.2013 Ağaç Gerçekleştirimi Daha iyisi: 1. Çocuk/Kardeş Gösterimi Her düğümde iki bağlantı bilgisi tutularak hem çocuk hem de yandaki kardeş tutulabilir. İstenildiği kadar çocuk/kardeş olabilir. JAVA Declaration class AgacDugumu { int eleman; AgacDugumu ilkCocuk; AgacDugumu kardes; } A B C E D F 19 İkili Ağaç İkili Agaç (Binary Tree) : Kök olarak adlandırılan özel bir düğüm vardır. – Her düğüm en fazla iki düğüme bağlıdır. – Kök hariç her düğüm bir daldan gelmektedir. – Tüm düğümlerden yukarı doğru çıkıldıkça sonuçta köke ulaşılır İkili Arama Agacı (Binary Search Tree) : Bos olan veya her dügümü asagıdaki sartlara uyan anahtara sahip bir ikili agaçtır : • Kökün solundaki alt ağaçlardaki (eger varsa) tüm anahtarlar kökteki anahtardan küçüktür. • Kökün sağındaki alt ağaçlardaki (eğer varsa) tüm anahtarlar kökteki anahtardan büyüktür. • Sol ve sag alt agaçlar da ikili arama agaçlarıdır. Dr.Sinan TUNCEL 20 10 27.12.2013 İkili Ağaç Full binary tree : i) Her yapragı aynı derinlikte olan ii) ii) Yaprak olmayan dügümlerin tümünün iki çocugu olan agaç Full (Strictly) Binary Tree'dir. iii) Bir full binary tree'de n tane yaprak varsa bu agaçta toplam 2n-1 dügüm vardır. Complete binary tree : Full binary tree'de yeni bir derinlige soldan saga dogru dügümler eklendiginde olusan agaçlara Complete Binary Tree denilir. Böyle bir agaçta bazı yapraklar digerlerinden daha derindir. Bu nedenle full binary tree olmayabilirler. En derin düzeyde dügümler olabildigince soldadır. General Tree (Agaç) : Her düğümün en fazla iki çocugu olabilme sınırı olmayan ağaçlardır. Dr.Sinan TUNCEL 21 İkili Ağaç İkili ağac bir düğümün en fazla 2 tane çocuğa sahip olabildiği ağaçtır Her düğüm en fazla 2 çocuğa sahip olabilir. Bilgisayar bilimlerinde en yaygın ağaçtır. Kök A A A B B D C İki farklı ikili ağaç Z P I K M Sağ alt ağaç 22 11 27.12.2013 İkili Ağaç (devam) N tane düğüm veriliyor, İkili ağacın minimum derinliği nedir. Derinlik 1: N = 1 = 20 düğüm Derinlik 2: N = 2 ve 3 düğüm = 21 ve 21+1 -1 düğüm Herhangi bir d derinliğinde, N = ? 23 İkili Ağaç (devam) • • • • Derinlik 0: N = 1 = 20 düğüm Derinlik 1: N = 2 ve 3 düğüm = 21 ve 21+1 -1 düğüm D derinliğinde , N = 2d ve 2d+1-1 düğüm (tam bir ikili ağaç) En küçük derinlik: log N ≤ d ≤ log(N+1)-1 or Θ(log N) 24 12 27.12.2013 İkili Ağaç (devam) N düğümlü ikili ağacın minimum derinliği: Θ(log N) İkili ağacın maksimum derinliği ne kadardır? Dengesiz ağaç: Ağaç bir bağlantılı liste olursa! Maksimum derinlik = N Amaç: Arama gibi operasyonlarda bağlantılı listeden daha iyi performans sağlamak için derinliğin log N de tutulması gerekmektedir. – – Bağlantılı liste Derinlik = N 25 İkili Ağaç Gerçekleştirimi d sol veri sag kök public class İkiliAgacDugumu { public İkiliAgacDugumu sol; public int veri; public İkiliAgacDugumu sag; } 4 12 6 45 7 26 13 27.12.2013 İkili Ağaç Gerçekleştirimi /* İkili ağaç düğümü oluşturur. */ İkiliAgacDugumu DugumOlustur(int veri){ İkiliAgacDugumu dugum = new İkiliAgacDugumu(); dugum.veri = veri; dugum.sol = null; dugum.sag = null; dugum veri null null return dugum; } • Bu yordam ikili ağaç düğümü oluşturur ve bunu geri döndürür. 27 İkili Ağaç Gerçekleştirimi İkiliAgacDugumu dugum = null; public static void main main(){ kok = DugumOlustur(4); kök 4 kok.sol = DugumOlustur(6); kok.sag = DugumOlustur(12); 12 6 kok.sol.sol = DugumOlustur(45); 45 7 1 kok.sag.sol = DugumOlustur(7); kok.sag.sag = DugumOlustur(1); } /* main */ • Kök verilmiş olsun tüm ağaç üzerinde dolaşıp elemanları ekrana nasıl yazdırırız.? − Ağaç dolaşma algoritmaları 28 14 27.12.2013 Kullanılan Verimli Arama Ağaçları Fikir: Verileri arama ağacı yapısına göre düzenlersek arama işlemi daha verimli olacaktır. 1. İkili Arama Ağacı (Binary search tree (BST)) 2. AVL Ağacı 3. Splay Ağacı 4. Red-Black Ağacı 5. B Ağacı ve B+ Ağacı 29 İkili Arama Ağaçı A İkili Arama Ağacı her bir düğümdeki değerlere göre düzenlenir: Sol alt ağaçtaki tüm değerler kök düğümünden küçüktür. Sağ alt ağaçtaki tüm değerler kök düğümünden büyüktür. Kök Kök 2 5 SolAA 7 3 SağAA 3 SağAA 7 4 2 <5 >2 8 >5 5 8 4 30 15 27.12.2013 İkili Arama Ağacı - Tanımlama BST Dugum x sol deger sag /* İKİLİ ARAMA AĞACI */ public class BST { Private BSTDugum kok; public public public public public public BST(){kok=null;} void Ekle(int deger); void Sil(int deger); BSTNode Bul(int key); BSTNode Min(); BSTNode Max(); public class BSTDugum { public BSTDugum sol; public int deger; public BSTDugum sag; } 3 4 2 9 }; 7 31 BST Operasyonları - Bul • Değeri içeren düğümü bul ve bu düğümü geri döndür. 15 K 1. 2. 3. 4. Aranan Sayı=13 kök kök SolA SagA <K >K Arama işlemine kökten başla if (aranaDeger == kok.deger) if (aranaDeger < kok.deger) else <15 >15 return kok; Ara SolAA Ara SagAA 32 16 27.12.2013 BST Operasyonları - Bul Kök Aranan 15 sayı=13 18 6 2 13 4 9 • • 30 7 3 public BSTDugum Bul(int deger){ return Bul2(kok, deger); } public BSTDugum Bul2(BSTDugum kok, int deger){ if (kok == null) return null; if (deger == kok.deger) return kok; else if (deger < kok.deger) return Bul2(kok.sol, deger); else /* deger > kok.deger */ return Bul2(kok.sag, deger); } Mavi renkli düğümler arama sırasında ziyaret edilen düğümlerdir. Algoritmanın çalışma karmasıklığı O(d) dir. (d = ağaçın derinliği) 33 BST Operasyonları - Bul Aynı algoritma while döngüsü yardımıyla yinelemeli şekilde yazılabilir public BSTDugum Bul(int deger){ BSTDugum p = kok; while (p){ if (deger == p.deger) return p; else if (deger < p.deger) p = p.sol; else /* deger > p.deger */ p = p.sag; } /* while-bitti */ return null; } //bul-Bitti • Yinelemeli versiyon özyinelemeli versiyona göre daha verimli çalışır. 34 17 27.12.2013 BST Operasyonları - Min Ağaçtaki en küçük elemanı içeren düğümü bulur ve geri döndürür. En küçük elemanı içeren düğüm en soldaki düğümde bulunur. Kökten başlayarak devamlı sola gidilerek bulunur. public BSTDugum Min(){ if (kok == null) return null; Kök 15 BSTDugum p = kok; while (p.sol != null){ p = p.sol; } return p; } 18 6 2 30 7 3 13 4 9 35 BST Operasyonları - Max Ağaçtaki en büyük elemanı içeren düğümü bulur ve geri döndürür. En büyük elemanı içeren düğüm en sağdaki düğümde bulunur. Kökten başlayarak devamlı sağa gidilerek bulunur. public BSTDugum Max(){ if (kok == null) return null; Kök 15 BSTDugum p = kok; while (p.sag != null){ p = p.sag; } return p; } 18 6 2 30 7 3 13 4 9 36 18 27.12.2013 BST Operasyonları – Ekle(int deger) • • • Eklenecek değeri içeren “z” isimli yeni bir düğüm oluştur. • Ö.g.: Ekle 14 z 14 NULL NULL Eklenecek “z” düğümü. z.deger = 14 Kökten başlayarak ağaç üzerinde eklenecek sayıyı arıyormuş gibi aşağıya doğru ilerle. z Kok 14 15 18 6 Yeni düğüm aramanın bittiği düğümün çocuğu olmalıdır. 2 30 7 3 13 4 9 Eklemeden Eklemedensonra önce 14 37 BST Operasyonları – Ekle(int deger) public void Ekle(int deger){ BSTDugum pp = null; /* pp p’nin ailesi */ BSTDugum p = kok; /* Kökten başla ve aşağıya doğru ilerle*/ while (p){ pp = p; if (deger == p.deger) return; /* Zaten var */ else if (deger < p.deger) p = p.sol; else /* deger > p.deger */ p = p.sag; } /* Yeni değeri kaydedeceğimiz düğüm */ BSTDugum z = new BSTDugum(); z.deger = deger; z.sol = z.sag = null; if (kok == null) kok = z; /* Boş ağaca ekleme */ else if (deger < pp.deger) pp.sag = z; else pp.sol = z; } // ekleme işlemi bitti. 38 19 27.12.2013 BST Operasyonları – Sil(int deger) Silme işlemi biraz karmaşıktır. 3 durum var: 1. Silinecek düğümün hiç çocuğu yoksa (yaprak düğüm) – 2. Kök 15 Sil 9 Silinecek düğümün 1 çocuğu varsa – 18 6 Sil 7 2 30 7 3 13 4 14 9 3. Silinecek düğümün 2 çocuğu varsa 1. Sil 6 39 Silme: Durum 1 – Yaprak Düğümü Silme Kök Kök 15 15 18 6 2 30 7 3 13 4 18 6 2 30 7 3 4 13 9 Sil 9: Düğümü kaldırın ve bağlantı kısmını güncelleyin 9 silindikten sonra 40 20 27.12.2013 Silme: Durum 2 – 1 Çocuklu Düğüm Kök Kök 15 15 18 6 2 30 7 3 13 4 18 6 13 3 2 4 30 9 9 7 silindikten sonra Sil 7: Silinecek düğümün ailesi ve çocuğu arasında bağ kurulur 41 Silme: Durum 3 – 2 Çocuklu Düğüm Kök Kök 17 17 18 6 2 30 14 3 16 10 4 7 18 7 2 13 30 14 3 16 10 4 8 13 8 1) 2) 3) 4) Sil 6: Sağ alt ağaçtaki en küçük eleman bulunur.(7) Bu elemanın sol çocuğu olmayacaktır. 6 ve 7 içeren düğümlerin içeriklerini değiştirin 6 nolu eleman 1 çocuğu varmış gibi silinir. 6 silindikten sonra Not: Sağ alt ağaçtaki en küçük eleman yerine sol alt ağaçtaki en büyük eleman bulunarak aynı işlemler yapılabilir. 42 21 27.12.2013 İkili Ağaç Üzerinde Dolaşma İkili ağaç üzerinde dolaşma birçok şekilde yapılabilir. Ancak belirli bir yönteme uyulması algoritmik ifadeyi kolaylaştırır. İkili ağaç üzerinde dolaşmak için 3 temel yol vardır. Bunlar: Önce-kök (Preorder): Kök, Sol, Sağ Önce ağacın kökü, sonra sol alt ağaç ve ardından sağ alt ağaç Ortada-kök (Inorder): Sol, Kök, Sağ Önce sol alt ağaç, kök ve sağ alt ağaç Sonra-kök (Postorder): Sol, Sağ, Kök Önce sol alt ağaç, sağ alt ağaç ve kök. 43 Örnek Kök Önce-kök ACPDZMIK A Ortada-kök PCAMZDIK D C Z P M I Sonra-kök PCMZKIDA K 44 22 27.12.2013 Algoritma OnceKok(IkiliAgacDugumu kok){ if (kok == null) return; System.out.print(kok.veri+" "); OnceKok(kok.sol); OnceKok(kok.sag); } OrtadaKok(IkiliAgacDugumu kok){ if (kok == null) return; OrtadaKok(kok.sol); System.out.print(kok.veri+" "); OrtadaKok(kok.sag); } SonraKok(IkiliAgacDugumu kok){ if (kok == null) return; SonraKok(kok.sol); SonraKok(kok.sag); System.out.print(kok.veri+" "); } 45 Aynı Sayılarla Başa Çıkma Ağaç içerisindeki aynı sayılarla aşağıda verilen iki şeklide başa çıkılabilir: Düğümde saklanan bir sayaç değişkeni ile Veya Düğümde kullanılan bağlantılı liste ile Kök 5 3 2 3 Kök 2 5 7 4 1 4 2 3 7 8 6 46 23 27.12.2013 İkili Arama ağacı Uygulamaları İkili arama ağacı harita, sözlük gibi birçok uygulamada kullanılır. İkili arama ağacı (anahtar, değer) çifti şeklinde kullanılacak sistemler için uygundur. Ö.g.: Şehir Bilgi Sistemi Posta kodu veriliyor , şehir ismi döndürülüyor. (posta kodu/ Şehir ismi) Ö.g.: telefon rehberi İsim veriliyor telefon numarası veya adres döndürülüyor. (isim, Adres/Telefon) Ö.g.: Sözlük Kelime veriliyor anlamı döndürülüyor. (kelime, anlam) 47 İyi çalışmalar… Dr.Sinan TUNCEL 48 24