Ağaç (Tree) Yapısı Bir aile ağacı, büyük ebeveynler, ebeveynler, çocuklar, teyzeler, amcalar gibi aile bireylerinin hiyerarşik yapısını gösterecek şekilde oluşturulur. Buna göre büyük ebeveynler ebeveynlerden bir üst seviyede, ebeveynler çocuklardan bir üst seviyede olacak şekilde aile ağacına yerleştirilirler. Bir öğrenci bilgi sisteminde, öğrencinin adı, adresi, aldığı dersler, her dersten aldığı vize ve final notları gibi öğrenciye ait bilgileri bir ağaç yapısında göstermek mümkündür. Burada olduğu gibi, veriler arasında hiyerarşik ilişkiyi farklı seviyeler ile gösteren veri yapısına ağaç denir. Ağaç Elemanları Ağaç yapısını oluşturan elemanlar ile ilgili tanımları şöyle verebiliriz: Düğüm (node) : Ağaç elemanlarının genel adı Kök (root) : Ağacın en yüksek seviyesindeki düğüm Dal (branch) : Bir düğüm ile kendinden alt seviyedeki düğümler arasındaki bağlantı Alt-ağaç (sub-tree): Bir düğüme dal ile bağlı olan ve kendisi de alt seviyelere olan bağlantısı ile ağaç oluşturan yapı Yaprak (leaf): Alt-ağacı olmayan ve en alt seviyede yer alan düğüm 1 İkili Ağaçlar (Binary Trees) En çok kullanılan ağaç yapılarından birisi ikili ağaç'lardır. Her düğüme en fazla iki alt-ağaç bağlanabilen veri yapısına ikili ağaç denir. Bu altağaçlar, sol-alt-ağaç ve sağ-alt-ağaç olarak isimlendirilirler. Bir ikili ağacın yüksekliği h iken yaprak düğümlere kadar, her alt ağaca bağlı iki düğüm varsa bu ağacın toplam düğüm sayısı şöyle hesaplanır: Kök seviyesindeki düğüm sayısı :1 1. seviyedeki en fazla düğüm sayısı : 21 2. seviyedeki en fazla düğüm sayısı : 22 : : h. seviyedeki en fazla düğüm sayısı : 2h +________________________________ Toplam düğüm sayısı : 2h+1-1 İkili Ağacın Lineer Gösterimi Yüksekliği h olan bir ikili ağacın elemanlarını 2h+1-1 uzunlukta bir dizide saklamak mümkündür. Ağaç diziye şöyle yerleştirilir: 1. Kök, dizinin ilk adresinde saklanır. 2. Eğer bir düğüm dizinin n. adresinde saklanıyorsa, bu düğüme bağlı sol-alt-düğüm 2n, sağ-alt-düğüm ise 2n+1 adresinde saklanır. Buna göre n=1 için yandaki ağaçta, 25'e bağlı düğümlerin adresi şöyle olur: Sol alt düğüm adresi (19) : 1*2 =2 Sağ alt düğüm adresi (47) : 1*2+1 = 3 İkili Ağaç Üzerinde İlerleme (Binary Tree Traversals) İkili ağaç üzerinde ilerlerken, ağacın her düğümüne sadece 1 defa uğranır. Algoritmaya bağlı olarak, ağaç üzerinde ilerleme 3 şekilde olabilir: 1. Preorder Traversal: Kök düğüm, sol-alt-ağaç, sağ-alt-ağaç 2. Inorder Traversal: Sol-alt-ağaç, kök, sağ-alt-ağaç 3. Postorder Traversal: Sol-alt-ağaç, sağ-alt-ağaç, kök 2 Preorder, Inorder ve Postorder dolaşımlarını yukarıdaki animasyondan izleyebilirsiniz. İkili Sıralama Ağacı (Binary Search Tree) İkili ağaç veri yapısının önemli kullanımlarından biri sayı ya da alfabetik bilgi sıralanmasıdır. Her bir düğümün bilgi içeriğinin sol tarafındaki düğümler kendisinden küçük, sağ tarafındakiler kendisinden büyük eşit olduğu ikili ağaç yapısına ikili sıralama ağacı denir. Yukarıdaki örnekte de görüldüğü gibi her bir düğümün değeri solundakilerden büyük, sağındakilerden küçüktür. Mesela 52 değerine sahip olan düğümün sağındaki düğümlerin hepsi 52'den büyük değerlere, solundakiler 52'den küçük değerlere sahiptir. Alt düğümler için de bu kural geçerlidir. 71 değerine sahip olan düğümün sağındaki düğümlerin hepsi 71'den büyük değerlere, solundakiler 71'den küçük değerlere sahiptir. 3 Huffman Ağaç Yapısı Bilgisayarda veri sıkıştırma tekniği olarak kullanılan ağaç yapısıdır. Veri sıkıştırma işlemine, verilerin daha az yer kaplaması amacıyla ihtiyaç duyulur. Huffman veri sıkıştırma yöntemi veri kaybı olmadan kullanılan en performanslı sıkıştırma tekniklerinden biridir. Huffman algoritması karakter kullanım oranlarına göre değişkenlik gösteren bir ağaç oluşturur. 19 kere 'a', 7 kere 'c', 2 kere 'b', 1 kere 'd' harfi kullanılan durumda, oluşan Huffman ağacı; 'a' = 1 'c' = 01 'b' = 001 'd' = 000 değerlerine sahip olur. Normal yöntemlerle, örnekteki her bir harf en az 2 bit (4 farklı harf için 00, 01, 10, 11 kullanılırsa) yer ayrılarak temsil edilir. Toplam 30 eleman olduğu için 30*2 = 60 bit gereklidir. Huffman ağacına göre 'a' harfi 1 bit (1 kullanılır), 'c' harfi 2 bit (01 kullanılır), 'b' harfi 3 bit (001 kullanılır) ve 'd' harfi 3 bit (000 kullanılır) yer ayrılarak temsil edilir. 19 tane 'a', 7 tane 'c', 2 tane 'd' ve 1 tane 'c' olduğundan, toplam bit sayısı 1*19 + 2*7 + 3*2 + 3*1 = 42 şeklinde hesaplanır. Kaynak: http://www.hikayihan.com/yazilim/huffman-kodlama-agaci/ 4 Örnek: (kaynak: http://www.csharpnedir.com/articles/read/?id=189) Sembol(Karakter) a b k m d ğ Sembol Frekansı 50 35 20 10 8 4 Bu tablodan çıkarmamız gereken şudur : Elimizde öyle bir metin dosyası varki "a" karakteri 50 defa, "b" karakteri 35 defa .... "ğ" karakteri 2 defa geçiyor. Amacımız ise her bir karakteri hangi bit dizileriyle kodlayacağımızı bulmak. 5 6 7 Frekans 50 35 20 10 8 4 Sembol(Karakter) a b k m d ğ Bit Sayısı 1 2 3 4 5 5 Huffman Kodu 0 10 110 1110 11111 11110 Ascii kodları ile hafızayı kayıt edilseydi, (50+35+20+10+8+4)x8=1016 bit yer kullanılacaktı. Bu sıkıştırma tekniği ile, (50x1)+(35x2)+(20x3)+(10x4)+(8x5)+(4x5)=280 bit yer kullanılacak Öncelik Kuyruğu (Heap) Yapısı Bir yazıcı kuyruğunda 1000 sayfalık ve 1 sayfalık işler olduğunda, işlem önceliğini az olana yani 1 sayfalık işe vermek gerekir. Aynı şekilde işletim sistemi de küçük işlere büyük işlerin bekletmesinden kurtulması amacıyla öncelik tanımaktadır. Bu sistemi gerçekleştirebilmek için veriler içerisinden en küçüğü tespit edecek ve çıkartacak bir algoritmaya ihtiyaç duyulur. Daha önce anlatılan veri yapılarından bağlı listeler ve sıralı diziler üzerinde en küçük elemanı tespit etmek ve çıkarmak mümkündür. Bağlı listeye eleman eklemek O(1) (en öne eklenir), en küçük elemanı tespit edip silmek O(n) (listeyi dolaşmak gerekir) zamanı alır. Sıralı dizilerde ise eleman eklemek O(n) (elemanları bir sağa kaydırmak gerekir), en küçük elemanı tespit edip silmek O(1) (en baştaki eleman en küçüktür) zamanı alır. Sonuç olarak, her iki metot birbirlerine avantaj sağlayamamaktadır, her birinin bütünü ele alındığında O(n) zamanı gerekmektedir. Eleman eklemenin mümkün olduğu ve en küçük elemanın tespit edilip çıkartılabildiği O(n)'den daha hızlı bir mantık, bir algoritma varsa tercih edilmelidir. Bu durumda karşımıza öncelik kuyruğu veri yapısı çıkar. Öncelik Kuyruğu yapısında eleman eklemek ve en küçük elemanı çıkarmak O(log2 n) zamanı almaktadır. Sonuç olarak öncelik kuyruğu yapısının bu problemin çözümünde kullanılması daha uygun olur. Öncelik kuyruğu yapısı tamamen dolu ikili ağaç yapısıdır. Arada boş düğümleri olmayan bir ağaç yapısı oluşturabilmek için ağacının katmanları soldan sağa olacak şekilde doldurulur. Ayrıca tamamen dolu ikili ağacı, dizi üzerinde göstermek kolaydır. Öncelik kuyruğu (heap) yapısı bazı kaynaklarda küme olarak da adlandırılmaktadır. 8 Küme (heap) yapısında her bir düğümün değeri çocuklarının değerlerinden küçüktür veya eşittir. Bu durumda en küçük değere sahip eleman köktür. 9 Öncelik Kuyruğu (Heap) İşlemleri Öncelik kuyruğu (heap) yapısında sadece iki işlem yapmak mümkündür; eleman ekleme, en küçük elemanı çıkarma. Bunun dışında eleman arama gibi işlemler yapmak mümkün değildir. Bu bir dezavantaj gibi gözükse de birçok problemin çözümünde küme (heap) yapısı kullanılmaktadır. a. Öncelik Kuyruğuna Eleman Ekleme Küme (heap) yapısına eleman eklemek için, ilk önce bir sonraki uygun yere eklenmek istenen eleman geçici olarak konulur, ikinci adım olarak yeni eklenen düğüm babası ile karşılaştırılır, küçükse yer değiştirilir. Karşılaştırma ve yer değiştirme işlemine yeni eklenen eleman küçük olmayıncaya veya köke ulaşıncaya kadar devam edilir. Böylece küme (heap) yapısına eleman ekleme işlemi tamamlanmış olur. Küme (heap) yapısına eleman ekleme işlemi, en fazla ağacın derinliği kadar yer değiştirme yapılacağından O(log2 n) zamanı alır. 10 b. Öncelik Kuyruğundan En Küçük Elemanı Çıkarma Küme (heap) yapısından en küçük elemanı çıkarmak için, ilk önce kökteki eleman (en küçük eleman) silinir, ikinci adım olarak en sondaki eleman köke yerleştirilir, üçüncü adımda ise, köke yerleştirilen elemanın çocukları ile karşılaştırılarak, büyükse küçük olanla yer değiştirilir. Karşılaştırma ve yer değiştirme işlemine çocukların ikisi de büyük oluncaya kadar devam edilir. Böylece küme (heap) yapısından en küçük elemanı çıkarma işlemi tamamlanmış olur. Küme (heap) yapısından en küçük elemanı çıkarma işlemi, kökün silinmesi 1 işlem, kümenin (heap) tekrar düzenlenmesinde en fazla ağacın derinliği kadar yer değiştirme yapılacağından log2n işlem, toplam O(log2 n) zamanı alır. Küme (heap) yapısı hem eleman ekleme, hem de eleman çıkarma işlemlerini O(log2 n) zamanında gerçekleştiren hızlı bir mantıktır. Ayrıca dizilere diğer ağaç yapılarına göre daha kolay uyarlanabilmektedir. Küme (heap) yapısı en çok, hızlı bir sıralama algoritması olarak kullanılmaktadır. 11