VERİ YAPILARI LİSTELER Yrd. Doç. Dr. Murat GÖK Bilgisayar Mühendisliği Bölümü YALOVA ÜNİVERSİTESİ
Bağlı Listeler Aynı kümeye ait veri parçalarının birbirlerine bellek üzerinde, sanal olarak bağlanmasıyla oluşturulurlar. Dizilerden sonra en sık kullanılan veri depolama yapısıdır. Tüm veri, bir tren katarı gibi birbirine bağlı parçalardan oluşur. Bağlantılı listede birisi veri, diğeri bağlantı bilgisi olmak üzere temelde iki kısım bulunur. Veri kısmında o uygulama için gerekli olan bilgi bulunur. Bağlantı kısmında bağlantının nereye yapılacağını gösteren bir veya birkaç adres bilgisi bulunabilir.
Diziler vs. Bağlı Listeler Dizilerin boyutu genellikle program tasarım esnasında (statik olarak) belirlenir. Bellekte dizi için ayrılan blok, çalışma zamanında kullanılmasa bile yer işgal eder. Diziler, elemanlarını ayrılan blok içerisinde ardışık olarak tutarlar. Dizi elemanlarına erişim indeks numarası ile olur. Böylece işaretçi değişkene gerek kalmaz. Arama: Sıralı bir dizi de arama yapma zaman karmaşıklığı O(log n) dir. Fakat sıralı olmayan bir dizi de arama yapma O(n) dir. Ekleme: Sıralı bir diziye ekleme yapma için önce eklenecek yer belirlenmeli ondan sonra boş yer açmak için elemanlar bir kaydırmalıdır. Bu ise O(n) zaman gerektirir. Sıralı olmayan diziye ekleme ise O(1) zamanında olur. Silme: Hem sıralı hem de sıralı olmayan diziden silme işlemi arama gerektirir. Sonrasında sıralı diziden silme gerçekleştirildikten sonra boş yerin doldurulması için elemanlar bir sıra kaydırılır. Her ikisinin de zaman karmaşıklığı O(n) dir. Bağlı listeler ise belleğin sadece bir bloğunu değil ihtiyaç duyduğu kadarını kullanırlar. Bu nedenle bellek yettiği sürece bağlı listelere eleman eklenebilir. Bağlı listeler, verileri bellek içinde ardışık olmayan bir adresleme ile tutarlar. Bir sonraki elemana işaretçi değişken ile erişilir. Arama: Liste içinde aranan bir elemana direkt olarak erişilemez, liste eleman zinciri baştan sona tek tek aranarak erişilir. Arama, O(n) zaman gerektirir. Ekleme: Verinin eklenmesi için önce ekleneceği yer aranır. Bu işlem O(n) zamandır. Verinin belirlenen yere eklenmesi ise O(1) zamanında olur. Silme: Silme işlemi, ekleme işlemi ile aynı zaman karmaşıklığı ve adımlara sahiptir. Listeler, ekleme ve silme de dizilerden daha iyi performansa sahiptir. Çünkü her hangi bir eleman kaydırmaya ihtiyaç duymaz. Liste üzerinde ara elemanlara kolayca erişilememesi nedeniyle sık sık arama işlemi gerektiren algoritmalarda çok tercih edilmez.
Bağlı Liste Çeşitleri Tek bağlı listeler (Singly linked lists) Çift bağlı listeler (Doubly linked lists) Çevrimsel listeler (Circular lists) Bağlı Liste Temel İşlemleri Listede gezinme (List traversal) Bir düğümün aranması (Searching a node) Bir düğümün eklenmesi (Insert a node) Bir düğümün silinmesi (Delete a node)
Bir dizi, bir bağlı liste ve bir çift bağlı liste de o1, o2, o3, o4 ve o5 verilerinin saklanması Bellekte bir dizi, bir bağlı liste ve bir çift bağlı liste de o1, o2, o3, o4 ve o5 verilerinin saklanması
Tek bağlı listeler Java da bağlı liste tanımlama: class Link { public int idata; // veri public double ddata; // veri public Link next; // referans } Boş bir bağlı liste de next işaretçi değişkeni değeri null dur. next = NULL; C de bağlı liste tanımlama: struct Node { Object element; //veri Node *next; // işaretçi };
Çift bağlı listeler Üstünlükleri: Tek bağlı listeler ile hareket (traverse) yönü sadece listenin başından sonuna doğrudur. Bu durum bir düğümden geriye gidilmesine izin vermemektedir. Çift bağlı listeler (ÇBL) ile bu sorun çözülmüştür. ÇBL ile bir düğüm ekleme veya silme işlemi, bir önceki düğüme gitme gereksinimi ortadan kalktığı için kolaylaşmıştır. Kısıtları: ÇBL Önceki düğümün adresini tutmak için ekstra işaretçi (ve dolayısıyla alan) gerektirir.
Çevrimsel listeler Listenin son elemanın işaretçi değişkeni NULL değil, ilk elemanın adresini gösterir. Böylece sonlu bir çevrimsel yapı oluşur. İşletim sisteminde belli sayı da işlemin (process) aynı kaynağı (resource), sabit zaman diliminde kullanacağı bir yapı çevrimsel liste ile oluşturulabilir.
EK-1 Traversing a linked list Node *pwalker; int count = 0; cout << List contains:\n ; for (pwalker=phead; pwalker!=null; pwalker = pwalker->next) { count ++; cout << pwalker->element << endl; }
EK-2 Searching a node in a linked list pcur = phead; // Search until target is found or we reach // the end of list while (pcur!= NULL && pcur->element!= target) { pcur = pcur->next; } //Determine if target is found if (pcur) found = 1; else found = 0;
EK-3 Insertion in a linked list a b current tmp x tmp = new Node; tmp->element = x; tmp->next = current->next; current->next = tmp; Or simply (if Node has a constructor initializing its members): current->next = new Node(x,current->next);
EK-4 Deletion from a linked list a x b current Node *deletednode = current->next; current->next = current->next->next; delete deletednode;