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 Genelleştirilebilinir mi? Soyut 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 queue – kuyruk 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, ekle-insert, 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 set-kü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 Hata ayıklaması (debug) kolaydır. Birden fazla kişinin aynı anda beraber çalışmasına uygundur. 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. 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 Ai follows (takip eder) Ai-1
İş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ı printList ve find: doğrusal findKth: sabit insert ve delete: yavaş ö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 Bağlanmış düğümler serisine bağlantılı liste denir 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 eder node 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 data; // data Node* next; // 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; } // constructor ~List(void); // 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) Adımlar index’inci elemandan sonra verisi x’e eşit olan düğümü ekle (örnek., index = 0 iken, düğümü ilk eleman olarak ekle; index = 1 iken, ilk elemandan sonra düğüm ekle.) Eğer ekleme başarılı ise, eklenmiş düğümü dönder yoksa, return NULL. (Eğer index < 0 veya > liste uzunluğu ise , ekleme başarısız olacak.) Adımlar 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 En öne ekle En sona ekle Ortaya ekle 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 Try to locate index’th node. If it doesn’t exist, return NULL. 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 = new Node; newNode->data = x; if (index == 0) { newNode->next = head; head = newNode; else { newNode->next = currNode->next; currNode->next = newNode; return newNode;
Yeni bir düğüm ekleme Create a new node 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 = new Node; newNode->data = x; if (index == 0) { newNode->next = head; head = newNode; else { newNode->next = currNode->next; currNode->next = newNode; return newNode; Create a new node
Yeni bir düğüm ekleme Insert as first element 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 = new Node; newNode->data = x; if (index == 0) { newNode->next = head; head = newNode; else { newNode->next = currNode->next; currNode->next = newNode; return newNode; Insert as first element head newNode
Yeni bir düğüm ekleme Insert after currNode 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 = new Node; newNode->data = x; if (index == 0) { newNode->next = head; head = newNode; else { newNode->next = currNode->next; currNode->next = newNode; return newNode; Insert after currNode currNode 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 Adımlar InsertNode, gibi iki özel durum vardır. int DeleteNode(double x) Listeden verisi x from the list. Böyle bir düğüm varsa , pozisyonunu dönder. Yoksa, return 0. 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. InsertNode, gibi iki özel durum vardır. İlk düğümü sil Ortadaki veya sonraki düğümü sil.
Düğüm silme Try to find the node with its value equal to x 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; return currIndex; return 0; Try to find the node with its value equal to x
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; return currIndex; return 0; prevNode currNode
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; return currIndex; return 0; head currNode
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; }
List ‘ in kullanımı result int main(void) { List list; 6 7 5 Number of nodes in the list: 3 5.0 found 4.5 not found Number of nodes in the list: 2 result int main(void) { List list; list.InsertNode(0, 7.0); // successful list.InsertNode(1, 5.0); // successful list.InsertNode(-1, 5.0); // unsuccessful list.InsertNode(0, 6.0); // successful list.InsertNode(8, 4.0); // unsuccessful // print all the elements list.DisplayList(); if(list.FindNode(5.0) > 0) cout << "5.0 found" << endl; else cout << "5.0 not found" << endl; if(list.FindNode(4.5) > 0) cout << "4.5 found" << endl; else cout << "4.5 not found" << endl; list.DeleteNode(7.0); return 0; }
Bağlantılı Liste Çeşitleri Dairesel (Çevrimsel) bağlantılı listeler Son düğüm listedeki ilk düğümü işaret eder 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.) A B C Head
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 B C Head
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
Polinomial SVT … Bağlantılı liste kullanılarak uygulanması Eğer Aj katsayıları sıfırdan farklı ise kabul edilebilirdir, diğer durumda istenmez. Örnek: Çarp 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.