Listeler İçerik Soyut Veri Yapısı - Abstract Data Type (ADT) Liste SVY Liste SVY nın Dizi ile gerçekleştirilmesi Bağlantılı Listeler Temel İşlemler Ekleme - Insert, Bul- find, sil-delete, yaz-print, etc. Bağlantılı liste türevleri Dairesel (Circular) bağlantılı listeler Çift-yönlü (Doubly) bağlantılı listeler Soyut Veri Yapısı Veri tipi Nesneler kümesi + işlemler kümesi Örnek : integer Tamsayılar kümesi işlemler: +, -, x, / Genelleştirilebilinir mi? (örnek prosedürler bir işlem kavramını genelleştirir) Evet! Soyut veri tipi Yüksek-seviyede soyutlama high-level abstractions (soyutlama aracılığıyla karmaşıklık kontrolü) Kaysülleme (Encapsulation) / giydirme Kapsülleme SVT üzerindeki işlemler sadece uygun fonksiyonun çağrılması ile yapılabilir. Tip tanımı ve bu tip üzerindeki işlemler, programın bir bölümüne yerleştirilebilinir. Eğer SVT nin gerçekleştirilmesi değiştirmek isteniyorsa Nereye bakacağımızı biliyoruz. Bir kısmını değiştirmekle programın başka yerlerinde hata çıkmayacağından emin oluruz. SVT basit tipler gibi davranabiliriz: Alt plandaki gerçekleştirilmesiyle ilgilenmemize gerek kalmayabilir. SVT C++: class metot C++: member function üye fonksiyonu SVT… Örnekler set – küme SVT Elemanların kümesi işlemler: birleşim- union, kesişim-intersection, boyutu-size and tersi-complement queue – kuyruk SVT Elemanların art arda dizilmiş hali işlemler: boş kuyruk oluştur-create empty queue, ekleinsert, incele-examine, sil-delete, ve yoket-destroy İki SVT aynı değildir: Alt planda aynı modele sahip olmasına rağmen işlemleri farklıysa. Örnek. Sadece birleşim ve bul işlemleri içeren setküme SVT farklıdır. Gerçekleştirmenin uygunluyu çalıştırılan işlemlere çok bağlıdır. Avantaj ve Dezavantajları SVTlerinin kullanımı, gerçekleştirmesinden ayrıdır/ ayrılır. Modülerdir: bir SVT için bir modül SVT kodu farklı uygulamalar için tekrar kullanılabilir. Bilgi gizleme Belirli bir işi yapmak için tasarlanmış mantıksal birimdir. Kullanıcı programlarını etkilemeden gerçekleştirme detayları değiştirilebilir. Hızlı prototiplemeye müsaittir. Hata ayıklaması (debug) kolaydır. Birden fazla kişinin aynı anda beraber çalışmasına uygundur. Basit SVT gerçekleştirmeleri ile prototipini yap ve sonra gerekirse ayarlama yap. Verimlilik kaybı Liste SVT Sıfır veya birden fazla elemanların art arda dizilmiş hali A1, A2, A3, … AN N: liste uzunluğu A1: ilk eleman AN: son eleman Ai: i. Eleman / pozisyon If N=0, then listeyi boşalt Lineer olarak sıralanmış Ai precedes (önce gelir) Ai+1 A follows (takip eder) A İşlemler printList: listeyi yaz makeEmpty: boş liste oluştur find: listedeki bir elemanın pozisyonunu bul liste: 34,12, 52, 16, 12 find(52) 3 insert: listeye bir eleman ekle insert(x,3) 34, 12, 52, x, 16, 12 remove: listeden bir eleman sil remove(52) 34, 12, x, 16, 12 findKth: Belirli bir pozisyondaki elemanı getir. SVT Gerçekleştirmesi SVT ini ifade edecek bir veri yapısı seç Örnek: Diziler, kayıtlar vb. Each operation associated with the ADT is implemented by one or more subroutines Two standard implementations for the list ADT Array-based Linked list Dizi Gerçekleştirmesi Elemanlar art arda bir şekilde kaydediliyor. Dizi Gerçekleştirmesi... Listenin maksimum boyutunun bilinmesini gerektirir Yer israfı doğrusal findKth: sabit insert ve delete: yavaş printList ve find: örnek 0. pozisyona ekleme (yeni eleman) Öncelikle yer açmak için bütün dizinin bir hücre kaydırılmasını gerektirir. örnek 0. pozisyonda silme Bütün elemanların bir hücre yukarı kaydırılması gerekir Ortalama olarak her iki işlemde de listenin yarısının yer değiştirmesi gerekir. İşaretçi Gerçekleştirmesi (Bağlantılı Liste) Liste de elemanlar art arda depolanmayacaksa bağlantılı liste kullanılabilir Hafızada art arda olmasına gerek olmayan yapılardır. Her düğüm bir eleman ve kendisinden sonra gelen düğümüm adresini içeren bir işaretçi barındırır. Son hücre bir sonraki bağlantı olarak NULL değerini gösterir. Dizi gerçekleştirmesi ile karşılaştırılırsa, İşaretçi uygulaması gerektiği kadar alan kullanır Fakat herbir hücrede işaretçi için alan tutar. Bağlantılı Listeler A B C Baş Bağlanmış düğümler serisine bağlantılı liste denir Her düğüm en az aşağıdakileri içerir. Veri (herhangi bir tiple olabilir) Listedeki bir sonraki düğüme olan işaretçi Baş: İlk düğüme olan işaretçidir Son düşüm NULL’ a işaret edernode A veri işaretçi Basit bir Bağlantılı Liste Sınıfı İki sınıf kullanılır : Node ve List Node sınıfını düğümler için tanımla data: double-tipinde veri next: listedeki bir sonraki düğüme işaretçi class Node { public: double Node* }; data; next; // data // pointer to next Basit bir Bağlantılı Liste Sınıfı List sınıfı aşağıdakiler içerir head: listedeki ilk düğüme olan işaretçi. İlk başta liste boş olduğu için, head, NULL değerini alır. List üzerindeki işlemler class List { public: List(void) { head = NULL; } ~List(void); // constructor // destructor bool IsEmpty() { return head == NULL; } Node* InsertNode(int index, double x); int FindNode(double x); int DeleteNode(double x); void DisplayList(void); private: Node* head; }; Basit bir bağlantılı liste sınıfı List işlemleri IsEmpty: listenin boş oluş olmadığını belirle. InsertNode: belirlenen bir pozisyona yenib ir düğüm ekle FindNode: verilen bir değere sahip düğümü bul DeleteNode: verilen bir değere sahip düğümü sil DisplayList: listedeki bütün düğümleri listele Yeni bir düğüm ekleme Node* InsertNode(int index, double x) index’inci elemandan sonra verisi x’e eşit olan düğümü ekle Eğer ekleme başarılı ise, eklenmiş düğümü dönder yoksa, return NULL. (örnek., index = 0 iken, düğümü ilk eleman olarak ekle; index = 1 iken, ilk elemandan sonra düğüm ekle.) (Eğer index < 0 veya > liste uzunluğu ise , ekleme başarısız olacak.) Adımlar 1. 2. 3. 4. index’inci elemanı bul Yeni düğüm için hafızada yer ayır Yeni düğüm kendisinden sonrakini gösterecek Yeni düğümden önceki yeni düğümü gösterecek index’inci eleman newNode Yeni bir düğüm ekleme InsertNode ‘ da karşılaşılan durumlar Boş listeye ekle 2. En öne ekle 3. En sona ekle 4. Ortaya ekle 1. Gerçekte iki temel durum vardır. İlk düğüm olarak ekleme (Durum 1 and Durum 2) Ortaya veya sona ekleme (Durum 3 and Durum 4) Yeni bir düğüm ekleme Node* List::InsertNode(int index, double x) { if (index < 0) return NULL; Try to locate index’th node. If it doesn’t exist, return NULL. int currIndex = 1; Node* currNode = head; while (currNode && index > currIndex) { currNode = currNode->next; currIndex++; } if (index > 0 && currNode == NULL) return NULL; Node* newNode = newNode->data = if (index == 0) { newNode->next head } else { newNode->next currNode->next } return newNode; } new x; Node; = = head; newNode; = = currNode->next; newNode; Yeni bir düğüm ekleme Node* List::InsertNode(int index, double x) { if (index < 0) return NULL; int currIndex = 1; Node* currNode = head; while (currNode && index > currIndex) { currNode = currNode->next; currIndex++; } if (index > 0 && currNode == NULL) return NULL; Node* newNode = newNode->data = if (index == 0) { newNode->next head } else { newNode->next currNode->next } return newNode; } new x; Node; = = head; newNode; = = currNode->next; newNode; Create a new node Yeni bir düğüm ekleme Node* List::InsertNode(int index, double x) { if (index < 0) return NULL; int currIndex = 1; Node* currNode = head; while (currNode && index > currIndex) { currNode = currNode->next; currIndex++; } if (index > 0 && currNode == NULL) return NULL; Node* newNode = newNode->data = if (index == 0) { newNode->next head } else { newNode->next currNode->next } return newNode; } new x; Node; Insert as first element head = = head; newNode; = = currNode->next; newNode; newNode Yeni bir düğüm ekleme Node* List::InsertNode(int index, double x) { if (index < 0) return NULL; int currIndex = 1; Node* currNode = head; while (currNode && index > currIndex) { currNode = currNode->next; currIndex++; } if (index > 0 && currNode == NULL) return NULL; Node* newNode = newNode->data = if (index == 0) { newNode->next head } else { newNode->next currNode->next } return newNode; } new x; Node; = = head; newNode; Insert after currNode currNode = = currNode->next; newNode; newNode Bir düğüm bulma int FindNode(double x) Listede verisi x olan düğümü ara. Eğer böyle bir düğüm varsa pozisyonunu dönder,. Yoksa, return 0. int List::FindNode(double x) { Node* currNode = head; int currIndex = 1; while (currNode && currNode->data != x) { currNode = currNode->next; currIndex++; } if (currNode) return currIndex; return 0; } Düğüm silme int DeleteNode(double x) Listeden verisi x from the list. Adımlar İstenen düğümü bul (FindNode işlemine benzer) Bunulan düğümün işgal ettiği hafızayı boşalt (gözden çıkar) Bulunan düğümün öncekisi, bulunan düğümün sonrakisini gösterir şekilde ayarla. Böyle bir düğüm varsa , pozisyonunu dönder. Yoksa, return 0. InsertNode, gibi iki özel durum vardır. İlk düğümü sil Ortadaki veya sonraki düğümü sil. Düğüm silme int List::DeleteNode(double x) { Try to find the node Node* prevNode = NULL; its value equal to x Node* currNode = head; int currIndex = 1; while (currNode && currNode->data != x) { prevNode = currNode; currNode = currNode->next; currIndex++; } if (currNode) { if (prevNode) { prevNode->next = currNode->next; delete currNode; } else { head = currNode->next; delete currNode; } return currIndex; } return 0; } with Düğüm silme int List::DeleteNode(double x) { Node* prevNode = NULL; Node* currNode = head; int currIndex = 1; while (currNode && currNode->data != x) { prevNode = currNode; currNode = currNode->next; currIndex++; prevNode currNode } if (currNode) { if (prevNode) { prevNode->next = currNode->next; delete currNode; } else { head = currNode->next; delete currNode; } return currIndex; } return 0; } Düğüm silme int List::DeleteNode(double x) { Node* prevNode = NULL; Node* currNode = head; int currIndex = 1; while (currNode && currNode->data != x) { prevNode = currNode; currNode = currNode->next; currIndex++; } if (currNode) { if (prevNode) { prevNode->next = currNode->next; delete currNode; } else { head = currNode->next; delete currNode; } return currIndex; } head currNode return 0; } Bütün elemanları yazdırma void DisplayList(void) Bütün düğümlerin verilerini yazdır Listedeki düğüm sayısını yazdır. void List::DisplayList() { int num = 0; Node* currNode = head; while (currNode != NULL){ cout << currNode->data << endl; currNode = currNode->next; num++; } cout << "Number of nodes in the list: " << num << endl; } Listeyi yoketme ~List(void) destructor u kullanarak liste tarafından işgal edilen hafızayı serbest bırak. Listedeki her bir düğümü birer birer sil. List::~List(void) { Node* currNode = head, *nextNode = NULL; while (currNode != NULL) { nextNode = currNode->next; // destroy the current node delete currNode; currNode = nextNode; } } 6 7 5 Number of nodes in the list: 3 5.0 found 4.5 not found 6 5 Number of nodes in the list: 2 result List ‘ in kullanımı int main(void) { List list; list.InsertNode(0, 7.0); list.InsertNode(1, 5.0); list.InsertNode(-1, 5.0); list.InsertNode(0, 6.0); list.InsertNode(8, 4.0); // print all the elements list.DisplayList(); if(list.FindNode(5.0) > 0) else if(list.FindNode(4.5) > 0) else list.DeleteNode(7.0); list.DisplayList(); return 0; } // // // // // successful successful unsuccessful successful unsuccessful cout cout cout cout << << << << "5.0 "5.0 "4.5 "4.5 found" << endl; not found" << endl; found" << endl; not found" << endl; Bağlantılı Liste Çeşitleri Dairesel (Çevrimsel) bağlantılı listeler Son düğüm listedeki ilk düğümü işaret eder A Head B C Listeyi gezmeyi ne zaman bitireceğimizi nasıl bileceğiz? (İpucu: current node işaretçisinin kafa (baş) ı işaret edip etmediğini kontrol et.) Bağlantılı Liste Çeşitleri Çift bağlantılı liste (Doubly linked lists) Herbir düğüm hem öncekini hem sonrakini işaret eder. İki NULL vardır: listenin ilk ve son düğümlerinde Avantajı: verilen düğümde, öncekini ziyaret etmek kolaydır. Listeleri ters yönde gezmek kolayıdır. A Head B C Dizi ve Bağlantılı Listeler Bağlantılı listelerin kodlaması ve yönetimi dizilerden daha zordur fakat kendine has avantajları vardır. Dinamik: bir bağlantılı liste kolaylıkla büyüyebilir ve daralabilir. Listede kaç düğüm olması gerektiğini bilmemize gerek yoktur. Gerektikçe hafızada oluşturulur. Buna karşılık C++ ‘ da dizi boyutu derleme zamanında sabittir. Kolay ve hızlı ekleme ve silme Dizide ekleme ve silme için geçici değişkenlere kopyalamak ve boşluk açmak veya boşluğu silmek gerekir. Bağlantılı listede ise düğümlerin hareket etmesine gerek yoktur. Sadece işaretçilerin ayarları değiştirilir. Örnek: Polinomial SVT Tek- değişkenli polinomial için SVT Dizi gerçekleştirmesi N f ( x) ai x i i 0 Polinomial SVT … Eğer Aj katsayıları sıfırdan farklı ise kabul edilebilirdir, diğer durumda istenmez. Örnek: Çarp P1 ( x) 10 x1000 5 x14 1 P2 ( x) 3x1990 2 x1492 11x 5 Zamanın çoğu sıfırların çarpımı için ve var olmayan parçaların çarpımı için harcanır. Bağlantılı liste kullanılarak uygulanması Herbir terim bir hücrede tutulur ve üstel değerlerin azalmasına göre sıralanır.