LİSTELER Liste sözcüğü aralarında bir biçimde öncelik-sonralık ya da altlık-üstlük ilişkisi bulunan veri öğeleri arasında kurulur[4]. Yada Aynı kümeye ait verilerin bellek üzerinde bir gösterici (pointer) yardımı ile birbirine bağlanması sonucu oluşturulan veri yapısıdır. Bu veri yapısındaki bütün elemanların ortak noktası kendi içlerinde bağlantı bilgisi içeren kendi türünden bir ya da daha fazla göstericiye sahip olmasıdır. Veri yapısı, kümedeki herhangi bir elemanın, kendisinden önce ve kendisinden sonra hangi elemanın bulunduğu bilgisi bu göstericilere değer vererek kurulur[5]. Dizilerin önemli bir özelliği boyutlarının zaman içinde sabit kalmasıdır. İki veya daha çok boyutlu dizilerde ise tabloların satır ve sütün sayısı değişmez. Yani, tablolar dikdörtgen şeklindedir. Böyle olunca bir dizinin fiziksel belleğe eşlenmesi basit bir çevirme işlemi ile yapılabilir (Şekil 1 ve Şekil 2). Bunun tersine, dinamik veri yapılarının boyutu da, şekli de süreç içinde değişir. Pratik uygulamalarda uğraştığımız verilerin boyutu değişken olabilir[1]. Not[0] Not[1] Not[2] Not[3] Not[4] Not[5] Not[6] Not[7] Not[8] Not[9] Bellek …...... 1. Eleman 2. Eleman 3. Eleman 4. Eleman 5. Eleman 6. Eleman 7. Eleman 8. Eleman 9. Eleman 10. Eleman …….. Dizinin ilk. elemanı Not[0]=…… Dizinin son. elemanı Not[9]=…… Şekil 1: C programlama dilinde tamsayı tipinde tanımlanmış 10 elemanlı tek boyutlu dizi (int not[eleman sayısı])[2]. Sütunlar 1. satır 1. sütün 2. satır 3. sütün 3. satır 4. sütün S a t ı r l a r Şekil 2: C programlama dilinde tamsayı tipinde tanımlanmış 12 elemanlı çok boyutlu dizi (int notlar[boyut 1] [boyut 2] [boyut 3]….. [boyut N])[2]. Belleğin dinamik olarak yönetilmesine örnek olarak; bir dizi tanımlamak istiyoruz ve bu dizinin boyutunu programın çalışma anında değiştirmek istiyoruz.(NOT: Diziler derleyici tarafından derleme aşamasında ele alınır. Bu yüzden çalışma anında dizi boyutlarını değiştirmek mümkün değildir). İşte bunu yapabilmenin yolu belleğin dinamik olarak kullanılmasından geçer. Bir dizinin boyutunu dinamik olarak arttırıp azaltmak kodu daha verimli kılar, belleği daha verimli kullanmamızı sağlar. Örneğin C dilinde belleğin dinamik 1 olarak kullanılmasını sağlayan standart fonksiyonlar: malloc, realloc, calloc ve free fonksiyonlarıdır[3]. Şöyle bir örneklerde verilebilir: Bir bölgede yaşayan 0-2 yaş bebeklerin sayısını bulmak ve bu bebeklerle ilgili çeşitli verileri işlemek isteyen bir program için dinamik bir veri yapısı gerekir. Ya da bir görüntü içinde dikdörtgen şeklinde olmayan bir nesneyi, değişen satır veya sütün sayıları ile saklamak gerekebilir. Bu gibi durumlarda, verinin bellekte saklanabilmesi için uygun bir veri yapısına ihtiyaç olmasının yanında, bu veriye daha sonra nasıl erişileceği konusunda da yöntemler geliştirmek gerekir. Aşağıda, önce dinamik veri yapısı oluşturmak için geliştirilen imleç (pointer) kavramını, daha sonra da yaygın olarak kullanılan dinamik veri yapılarından olan bitişik ve bağlı listeleri göreceğiz[1]. 1. İmleçler (Pointerler) Dinamik veri yapısı oluşturmanın en temel kavramlarından birisi imleçlerdir. Bilgisayarlarda birçok fiziksel yer, nümerik adreslerle belirlenir (Şekil 3). Bellek Alanı ……. FAFF FB00 FB01 …… Bellek …… İşaret Adres 888 FB00 …… Belleğin Fiziksel Alanları Belleğin Nümerik Adresleri Şekil 3: Belleğin fiziksel alanları ve nümerik adresleri[2]. Nümerik değerli bir adres bilgisayarın belleğinde çok rahat saklanabilir. Eğer, bir veri grubunun adresi biliniyorsa, veri gayet kolay bulunabilir. O halde, verinin kendisi bellekteki bir hücrede saklandıktan sonra, o hücrenin adresi sayısal bir değer ile başka bir hücrede saklanabilir. Bu veriye erişmek için, önce verinin adresini saklayan hücreye, daha sonra da bu adresin yönlendirmesi ile verinin saklandığı hücreye erişilir. Bir bakıma, verinin adresini saklayan hücre verinin kendisinin saklandığı hücreyi işaret etmektedir. Bu sebepten dolayı, nümerik adresi saklayan, bu hücreye İngilizcede “işaret eden” anlamına gelen pointer adı verilmiştir[1]. İşaretçi (pointer), bellek alanındaki bir gözün adresinin saklandığı değişkendir. İşaretçilere, veriler değil de, o verilerin bellekte saklı olduğu belek gözlerinin başlangıç adresleri atanır[2]. İmleçler bilgisayar bilimlerinde pek çok değişik amaç için kullanılırlar. Örneğin, internetteki üstün metin (hypertext) komutlarını saklayan URL adresleri imleçten başka bir şey değildir. Tabii, URL’ler bilgisayarın ana belleğindeki bir yeri değil internetteki bir yeri gösterirler[1]. 2 Günümüzde birçok programlama dili imleçlerin bildirimine (decleration), atanmasına (allocation) ve işlenmesine (manipulation) olanak sağlamaktadır. Bu tür dilleri kıllanan bir programcı, bilgisayar belleği içinde karmaşık ağlardan oluşabilecek veri yapıları kullanan algoritmalar tasarımlayabilir[1]. 2. Bitişik Listeler Liste içinde bulunan elemanları bellekte saklamanın en kolay yöntemi, listenin elemanlarını sıra ile bilgisayarın hafızasında ayrılan tek bir bitişik bloğa yerleştirmektir. Listenin elemanlarındaki karakter sayısının belli bir değeri aşamayacağı varsayılarak, listedeki her eleman için blokta belli sayıda hücre ayrılır ve liste elemanları sıra sıra kendileri için ayrılan hücrelerin içine yerleştirilirler. Elemanların karakter sayısını 8 ile sınırlasak, bu liste için oluşturulan bitişik bloğun içinde her eleman için 8 hücrelik bir alt blok ayırırız. Listedeki elemanların karakterlerini ASCII kodu ile bu hücrelere sıra sıra yerleştiririz. Bu tür listelere Bitişik Listeler (Cotiguous Lists) denir[1]. Örnek: Aşağıda verilen isim listesini belleğe yerleştirelim. Bitişik Hafıza Bloğu Ali Derviş Evren İlke Kibele Ozan Özde Uygar A l i 1. İsim D e r v i ş . . . U y g a r 2. İsim 8. İsim Öncelikle bu isim listesini belleğe yerleştirebilmemiz için gerekli büyüklükte bir hafıza bloğu ayırırız. Şekil 4: Bitişik liste ile bellekte saklanan isimler[1]. Bir ismin içinde bulunan karakter sayısı 8’den daha az ise geri kalan hücreler boşluğa karşı gelen ASCII kodu ile doldurulur. Şekil 4’te gösterilen bitişik listede 8 adet isim saklamak için gereken bellek alanı 64 bitişik bellek hücresidir[1]. Bitişik listeler basit oldukları için birçok uygulamada rahatlıkla kullanılabilirler. Fakat, bu tür veri yapılarında listeye ekleme yapmak veya çıkarma yapmak sorun olur. Zira, listeden bir isim çıkarmak istediğimiz zaman bu isimden kalan boşluğu ortadan kaldırmak üzere listedeki geri kalan isimleri bu boşluğa doğru kaydırmamız gerekir. Listeye isim eklemesi ise daha da büyük bir sorundur. Zira, ekleme yapmak için bellekte ayrılmış bir alan mevcut olmayabilir. Bu tür problemleri gidermek için her bir ismi bellekte bitişik olan tek bir bloğa değil ayrı ayrı alanlara koymak gerekir[1]. 3