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.