VERİ YAPILARI VE PROGRAMLAMA (BIP116) Yazar: Doç.Dr.İ.Hakkı.Cedimoğlu
SAKARYA ÜNİVERSİTESİ Adapazarı Meslek Yüksekokulu Bu ders içeriğinin basım, yayım ve satış hakları Sakarya Üniversitesi ne aittir. "Uzaktan Öğretim" tekniğine uygun olarak hazırlanan bu ders içeriğinin bütün hakları saklıdır. İlgili kuruluştan izin almadan ders içeriğinin tümü ya da bölümleri mekanik, elektronik, fotokopi, manyetik kayıt veya başka şekillerde çoğaltılamaz, basılamaz ve dağıtılamaz. Copyright 2004 by Sakarya University All rights reserved No part of this course contenet may be reproduced or stored in a retrieval system, or transmitted in any form or by any means mechanical, electronic, photocopy, magnetic, tape or otherwise, without permission in writing from the University. Sürüm 1 Sakarya... 2004 S 1
AĞAÇ (TREE) YAPILARI Bu Haftanın Hedefi: Bu Haftanın Materyalleri Bu haftaki dersimizde kullanacağımız bir materyal bulunmamaktadır. Kullanılan semboller Animasyon Soru Veritabanı Bağlantılı Soru Simülasyon Püf Noktası 1
Giriş Yığınlar, kuyruklar ve bağlı listeler doğrusal (linear) veri yapılarıdır. Ağaçlar ise doğrusal olmayan belirli niteliklere sahip veri yapılarıdır. Ağaç biçiminde oluşturulan ve kök, dal ve yaprak gibi kavramlara uygun olarak düzenlenen veri yapılarına ağaç yapıları denir. Ağacın her bir elemanına düğüm (node) adı verilir. Yukarıdaki ağaç yapısında göre A, B, C,. K birer düğümdür. Ağacın en üstteki düğümüne kök (root) adı verilir. Bu ağaç yapısında A köktür. İki düğüm arasındaki bağa dal adı verilir. Yukarıdaki ağaç yapısında A ile B, A ile C arasında dal vardır. Bir düğümün bağlı olduğu ilk alt düğümlere o düğümün çocukları (child) denir. Yukarıdaki örnekte B ve C, A'nın; I, J ve K, E'nin çocuklarıdır. Bir düğüm, bağlandığı ilk üst düğümlerin babası (parent)'dır. C'nin babası A, I'nın babası E'dir. Bir düğümün bağlı olduğu tüm alt düğümlere o düğümün varisleri (descendant) denir. Yukarıdaki örnekte I, J, K, E ve F, C'nin varisleridir. Bir düğüm, bağlandığı tüm üst düğümlerin atası (ancestor)'dır. G ve H'nin ataları D, B ve A'dır. Kök kendi hariç tüm düğümlerin atasıdır. Sol ve sağ bağı boş olan düğümlere yaprak (leaf) adı verilir. Yukarıdaki ağaç yapısında G, H, I, J, K, F yapraklardır. Aynı babaya sahip düğümlere kardeş düğüm (sibling, brother) adı verilir. Örnek olarak G ile H, E ile F kardeştir. 2
En derindeki yaprağın kök düğümüne olan uzaklığına ağacın derinliği (depth of tree) denir. Örnekteki ağaç yapısının derinliği 3'tür. Bir düğümün kök düğümüne olan uzaklığına ise bu düğümün derinliği denir. B'nin derinliği 1, F'nin derinliği 2, H'nin derinliği 3'tür. Genel ağaç yapısında düğümlerdeki çocuk sayısında ve ağaç yapısında bir kısıtlama yoktur. Ağaç yapısına belli kısıtlamalar getirilmesiyle ağaç çeşitleri meydana gelmiştir. Mesela her yaprağı aynı derinlikte olan ağaç yapısına dengeli ağaç (blanced tree) denir. İkili ağaçlar (binary trees) ise düğümlerinde en fazla iki bağ içeren (0, 1 veya 2) ağaçlardır. Ağaç yapısı kısıtlamaların az olduğu ve problemin kolaylıkla uyarlanabileceği bir yapı olduğundan birçok alanda kullanılmaktadır. Örnek olarak işletim sistemlerinde kullandığımız dosya-dizin yapısı tipik bir ağaç modellemesidir. AĞAÇ ÇEŞİTLERİ İkili Ağaç (Binary Tree) Her düğümün en fazla iki düğüme bağlandığı ağaç türlerine ikili ağaç denir. En basit ağaçlar grubuna girdiklerinden programlarda uygulanması kolaydır. Sıralama algoritmalarında, derleyicilerde sözdizim çözümlemede, kodlama kuramında ve benzeri algoritmalarında bu veri yapısı kullanılır. Yukarıdaki örnekte de görüldüğü gibi ikili ağaç yapısında her düğüm en fazla iki çocuğa sahiptir İkili Sıralama Ağacı (Binary Search Tree) İkili ağaç veri yapısının önemli kullanımlarından biri sayı yada 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 3
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. 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. Veri kaybı olmadan kullanılan en iyi sıkıştırma tekniklerinden biri de Huffman veri sıkıştırma yöntemidir. 4
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. Huffman örnekte görüldüğü gibi ağaç yapısı veri kaybına yol açmadan sıkıştırma işlemini gerçekleştirmiş olur. Ö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. 5
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 (heap) veri yapısı çıkar. Öncelik Kuyruğu (heap) yapısında eleman eklemek ve en küçük elemanı çıkarmak O(log2n) zamanı almaktadır. Sonuç olarak öncelik kuyruğu (heap) yapısının bu problemin çözümünde kullanılması daha uygun olur. Öncelik kuyruğunun bir diğer adı da küme olarak geçmektedir. Küme (heap) 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. 6
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. 7
İkili Arama (Binary Search) Aramada kullanılan kayıt sayısının çok fazla olduğu durumlarda sıralı arama işlem yükünü oldukça fazlalaştıracaktır. Bu yüzden ikili arama işlem yükünü azaltan bir yöntem olarak tercih edilir. İkili aramanın yapılabilmesi için veri yapımızda yer alan elemanların daha önceden sıralanmış olması gerekmektedir. Elemanlar sıralı olduğu durumda ikili arama metodu önce aranan elemanın anahtarını veri yapısının tam ortasında yer alan elemanla karşılaştırmakta ve bu elemandan büyük veya küçük olma durumuna göre aramaya aynı yöntemle veri yapısının alt veya üst bölümünde devam etmektedir. Bu yöntemle her bir adımla aramanın gerçekleştirildiği veri kümesinin büyüklüğü yarıya düşürülmüş olur. İkili aramada zaman karmaşıklığı O(log 2 N)'dir. Bu yüzden kayıt sayısı çok fazla olan uygulamalar için uygundur. Örneğin 1 milyon tane kayıtın bulunduğu bir veri kümesinde, arama işlemi, log 2 10000000 ~ 20'den yaklaşık 20 çevrimde bulunabilir. Aynı işlemi sıralı arama ile yapılmış olsaydı ortalama 500 bin çevrim, en kötü durumda ise 1 milyon çevrim gerekirdi. İkili arama yöntemi, sıralı olsa bile, bağlantılı listeler üzerinde uygulanamaz. Çünkü bağlantılı listelerde herhangi bir düğüme, ilk düğüm hariç erişilemez. 8