Linked List (Bağlı Listeler)
DR. ŞAFAK KAYIKÇI
Linked List
Bağlı Liste her bir elemanın ayrı bir nesne olduğu doğrusal bir veri yapısıdır.
struct node{
int data;
struct node *next;
};
Linked List
•Bir listenin her bir elemanı düğüm(node) genellikle iki özellikten oluşur - veri ve bir sonraki düğüme referans.
•Son düğüm null değerini referans gösterir.
• Bağlı bir listeye giriş noktası, listenin başı(head) olarak adlandırılır. Başın ayrı bir düğüm değil, ilk düğüme referans olduğu not edilmelidir. Liste boşsa, kafa boş bir referanstır.
•Bağlantılı bir liste dinamik bir veri yapısıdır. Bir listedeki düğüm sayısı sabit değildir ve talep üzerine büyüyebilir ve daralabilir. Bilinmeyen sayıda nesneyle ilgilenmesi gereken herhangi bir uygulamanın bağlantılı bir liste kullanması gerekir.
•Bağlantılı bir listenin bir diziye karşı bir dezavantajı, münferit elemanlara doğrudan erişime izin vermemesidir. Belirli bir öğeye erişmek istiyorsanız, baştan başlamanız ve bu öğeye ulaşana kadar referansları takip etmeniz gerekir.
•Diğer bir dezavantaj, bağlantılı bir listenin bir diziyle karşılaştırıldığında daha fazla bellek kullanmasıdır - bir sonraki düğüme bir referans depolamak için ekstra hafıza kullanılır.
Doubly Linked List
Next ve prev olmak üzere çşft yönlü iki referans bulunur.
Örnek işlemler
Node Oluşturma
struct node{
int data;
struct node *next;
};
struct node* newNode = (struct node*)malloc(sizeof(struct node));
Başa ekleme
Yeni düğüm oluşturulur ve listenin başına eklenir.
void basaEkle(struct node* newNode) {
tmp = head;
newNode->next = tmp;
head = newNode;
}
Traversing (ilerleme)
Listenin başından başlıyıp, tüm elemanlarını gezerek ilerlemek.
tmp = head;
while(tmp->next != NULL) {
tmp = tmp->next;
}
Sona Ekleme
Listenin sonuna kadar gezinmek (traverse) gerekir. En sona yeni düğüm eklenir.
newNode->next = NULL;
tmp = head;
while(tmp->next != NULL) {
tmp = tmp->next;
}
tmp->next = newNode;
Sonrasına Ekleme
while((tmp!=NULL) && (tmp->data!=key)) {tmp = tmp->next;
newNode->next = tmp->next;} tmp->next = newNode;
Öncesine Ekleme
while((tmp!=NULL) && (tmp->data!=key)) {prev = tmp;
tmp = tmp->next;
}prev->next = newNode;
newNode->next = tmp;
Silme
while((tmp!=NULL) && (tmp->data!=key)) {prev = tmp;
tmp = tmp->next;
}prev->next = tmp->next;
Stack (Yığın)
DR. ŞAFAK KAYIKÇI
Random Access vs Sequential Access
• Diziler rastgele erişimli (random access) veri yapılarıdır. Herhangi bir öğeye doğrudan erişilebilir.
Örn : Kitabın sayfaları (Herhangi bir sayfa, diğerlerinden bağımsız olarak açılabilir).
• Bağlı Listeler sıralı erişim (sequential access ) veri yapısındadır. İstediğiniz öğeye ulaşmak için belirli bir sıra izlenmelidir.
Örn : Rulo kağıt veya bant - istediğiniz verilere ulaşmak için önceki tüm malzemelerin açılması gerekir
Yığınlar
• Son giren ilk çıkar (LIFO) ilkesine göre sokulan ve çıkartılan nesnelerin bir kabıdır.
• push , yığının üstüne bir öğe ekler
• pop , öğeyi üstten kaldırır.
• peek (top), en üstteki öğeyi gösterir.
Uygulamalar
• Bir yığının en basit uygulaması bir sözcüğü ters çevirmektir. Belirli bir kelimeyi yığmak için - harfe göre harf - ve ardından yığından gelen harfleri çıkartın.
• Başka bir uygulama, metin editörlerinde "geri al" mekanizmasıdır; Bu işlem, tüm metin değişikliklerini bir yığında tutarak gerçekleştirilir.
• Recursive (özyinelemeli) çalışan fonksiyonlar.
• Geri izleme : Bir dizi öğedeki en son veri öğesine erişmeniz gerektiğinde bir işlemdir. Bir labirentte çıkmaz bir noktaya ulaştığında, geri dönmek gerekir. Nereye? önceki seçim noktasına. Bu nedenle, her seçim noktasında tüm olası seçenekleri bir yığında depolanır. Sonra geriye doğru izleme, yığından bir sonraki seçimi yapmak anlamına gelir.
Örnekler
1. Dizi ile yığın yapısı
2. Bağlı liste ile yığın yapısı
• Bağlı liste ile başa eleman ekleme işlemine dayanır.
• Eklenen her eleman başa eklenirken, çıkarılan her eleman da baştan çıkarılmaktadır
Queue (Kuyruk)
DR. ŞAFAK KAYIKÇI
Kuyruk (Dizi ile)
• Kuyruk, ilk giren ilk çıkar (FIFO) ilkesine göre eklenen ve çıkartılan bir nesne kabıdır (doğrusal bir koleksiyon).
Örn : AİBÜ öğrenci servis kuyruğu
◦ Sadece 2 işlem vardır. Eklemeler (enqueue) sıranın arkasına yapılırken, silmeler (dequeue) önden yapılır.
◦ Silme işleminde front arttırılırken, ekleme işleminde rear arttırılır.
◦ Uygulamalar:
◦ Kuyruklar, yazıcı, disk, CPU gibi tek bir paylaşılan kaynak için bekleme listeleri olarak kullanılır.
◦ Kuyruklar MP3 medya oynatıcı, CD oynatıcı vb. uygulamaların çoğunda tampon olarak kullanılır.
◦ Sıra, şarkı listesini şarkı listesine eklemek ve kaldırmak için yürütme listesini medya oynatıcılarda tutmak için kullanılır.
◦ Kuyruklar işletim sistemlerinde kesintilerin ele alınması için kullanılır.
Kuyruk ( dizi ile problem)
Dairesel kuyruk kullanılmadığı zaman, dizi implementasyonun birtakım zorlukları vardır.
rear = max -1 rear = max -1
Çözüm – Circular Queue front = -1 and rear = max-1
Kuyruk (Liste ile)
• Bağlı listeye ek olarak, head’in yanında birde rear pointer tutulur.
• Eklenen her eleman “en arkadaki elemanın” bir arkasına (=>next) eklenir. (AddLast)
Ağaç Yapıları (Tree)
DR. ŞAFAK KAYIKÇI
Ağaç
• Ağaç, içerisinde bir kök düğüm olan ve geri kalanların kök düğümün çocukları olarak adlandırıldığı özyinelemeli (recursive) bir veri yapısıdır.
• Kök düğüm dışındaki düğümler, herbiri boş olmatan alt-ağaç (subtree) olarak adlandırlan kümelere bölünürler.
• Genel olarak, bir düğüm herhangi bir sayıda alt düğümü olablir ancak sadece tek bir atası vardır.
Ağaç
Kök Düğüm : Kök düğüm, ağaç hiyerarşisindeki en üst
düğümdür. Başka bir deyişle, kök düğüm herhangi bir ebeveyni olmayan bir düğümdür.
Alt Ağaç : Kök düğüm boş değilse, T1, T2 ve T3 ağacına kök düğümünün alt ağaçları denir.
YaprakDüğümü : Ağacın en alt düğümüdür. E – F – G – H
Yol : Ardışık kenarların dizisine yol denir. E düğümünün yolu A → B
→ E'dir.
Ata düğümü : Bir düğümün atası, kökten o düğüme giden bir yoldaki herhangi bir öncül düğümdür. Kök düğümün ataları yoktur. Resimde F düğümünün ataları B ve A‘dır.
Derece : Bir düğümün derecesi, bir düğümün sahip olduğu çocuk sayısına eşittir. Resimde B'nin derecesi 2'dir. Bir yaprak düğümünün derecesi sıfırdır. Tam bir ikili ağaç içinde, her bir düğümün derecesi 2'ye eşittir.
Seviye Numarası : - Ağacın her düğümüne, her düğümün üst öğesinden daha yüksek bir düzeyde bulunacak şekilde bir seviye numarası atanır. Ağacın kök düğümü daima 0 seviyesinde bulunur.
İkili Ağaç (Binary Tree)
İkili Ağaç, her bir düğümün en fazla iki çocuğa sahip olabileceği özel bir genel ağaç türüdür. İkili ağaç genellikle üç ayrık altküme ayrılır.
• Düğümün kökü
• Sol ikilli alt ağaç
• Sağ ikili alt ağaç
İkili Ağaç gösterimi (Linked List)
struct Node { int data;
Node *left;
Node *right;
};
İkili Ağaç gösterimi (Sıralı - Dizi)
Ağacın kök düğümü, dizinin 1. dizininde bulunacaktır.
Eğer bir düğüm endeksinde saklanırsa, sol ve sağ çocukları 2i ve 2i + 1 konumunda depolanacaktır.
Dizinin 1. dizini yani ağaç [1] 0 ise, ağacın boş olduğu anlamına gelir.
Ağaçlarda Dolaşım (Traverse)
1 Pre-order Traversal: Önce kök ve ardından sol alt ağaç ve sağ alt ağaç gezilir.
2 In-order Traversal: Önce sol alt ağaç, ardından sırasıyla kök ve sağ alt ağaç gezilir.
3 Post-order Traversal: Önce sol alt ağaç, sonra sağ alt ağaç ve en son kök gezilir.
Bu prosedürler, ağacın her alt ağacına yinelemeli olarak uygulanacaktır.
İkili Arama Ağacı (Binary Search Tree)
• Düğümlerin belirli bir düzende düzenlendiği bir ikili ağaç sınıfı olarak tanımlanabilir. Buna sıralı ikili ağaç da denir.
• İkili arama ağacında, sol alt ağaçtaki tüm düğümlerin değeri, kök değerinden daha azdır.
• Benzer şekilde, sağ alt ağaçtaki tüm düğümlerin değeri, kök değerinden büyüktür.
• Bu kural, kökün sol ve sağ alt ağaçlarına tekrar tekrar uygulanacaktır
Örn:
43, 10, 79, 90, 12, 54, 11, 9, 50 BST?
AVL Tree
DR.ŞAFAK KAYIKÇI
AVL Ağacı
•AVL Ağacı, 1962 yılında GM Adelson - Velsky ve EM Landis tarafından icat edilmiştir. Ağaç, mucitlerinin onuruna AVL olarak adlandırılmıştır.
•AVL Ağacı, her düğümün sağ alt ağacının yüksekliğinin sol alt ağacınınkinden çıkarılmasıyla hesaplanan bir denge faktörü ile ilişkilendirildiği yükseklik dengeli bir ikili arama ağacı olarak tanımlanabilir.
•Her düğümün denge faktörü -1 ile 1 arasındaysa ağacın dengeli olduğu, aksi takdirde ağacın dengesiz olacağı ve dengelenmesi gerektiği söylenir.
AVL Ağacı
Ekleme işlemleri
AVL ağacına ekleme, ikili arama ağacında yapıldığı gibi gerçekleştirilir. Yeni düğüm AVL ağacına yaprak düğümü olarak eklenir. Ancak ekleme ile birlikte dengesizlik oluşursa, ağaç döndürülerek dengelenebilir.
SAĞA
SOLA
Rotasyon
Rotasyon (döndürme)
Takma türüne bağlı olarak, döndürmeler dört kategoriye ayrılır.
SN rotasyon Açıklama
1 LL Döndürme Yeni düğüm, kritik düğümün sol alt ağacının sol alt ağacına ekleniyorsa
2 RR Döndürme Yeni düğüm, kritik düğümün sağ alt ağacının sağ alt ağacına ekleniyorsa 3 LR Döndürme Yeni düğüm, kritik düğümün sol alt ağacının sağ alt ağacına ekleniyorsa 4 RL Döndürme Yeni düğüm, kritik düğümün sağ alt ağacının sol alt ağacına ekleniyorsa
LL Döndürme
•Kritik düğüm z
•Sağa döndürelerek çözülür.
• T3’ün yer değiştirmesine dikkat !!
LL Döndürme - Örnek
Yandaki AVL ağacına 12 değerini ekleyiniz ?
RR Döndürme
•Kritik düğüm z
•Sola döndürelerek çözülür.
• T2’nin yer değiştirmesine dikkat !!
RR Döndürme - Örnek
Yandaki AVL ağacına 100 değerini ekleyiniz ?
LR Döndürme ( 2 adım)
LR Döndürme - Örnek
Yandaki AVL ağacına 70 değerini ekleyiniz ?
RL Döndürme (2 adım)
RL Döndürme - Örnek
Yandaki AVL ağacına 92 değerini ekleyiniz ?
Genel Örnek
63, 9, 19, 27, 18, 108, 99, 81
Silme -1
Silme -2
Simulasyon
https://www.cs.usfca.edu/~galles/visualization/AVLtree.html
Arama Algoritmaları
DR. ŞAFAK KAYIKÇI
Lineer Search (Doğrusal Arama)
Doğrusal arama çok basit bir arama algoritmasıdır. Bu tür bir aramada, tüm öğeler üzerinde birer birer sıralı bir arama yapılır. Her madde kontrol edilir ve eğer bir eşleşme bulunursa o zaman o madde geri döner, aksi takdirde veri toplama işleminin sonuna kadar arama devam eder.
Binary Search (İkili Arama)
Hızlı bir arama algoritmasıdır. Bu arama algoritması, böl ve yönet prensibi ile çalışır. Bu algoritmanın düzgün çalışması için veri sıralı biçimde olmalıdır.
İkili arama, koleksiyonun en ortasındaki öğeyi karşılaştırarak belirli bir öğeyi arar. Bir eşleşme olursa, o zaman madde dizini döndürülür. Ortadaki öğe maddeden büyükse, öğe, orta öğenin solundaki alt dizide aranır. Aksi halde, orta öğenin sağındaki alt dizide öğe aranır. Bu işlem, alt dizilimde, alt dizilimin boyutu sıfıra inene kadar devam eder.
Binary Search (Örnek)
Sıralama Algoritmaları
DR. ŞAFAK KAYIKÇI
Bubble Sort (Kabarcık – Baloncuk)
En sade algoritmadır
Komşu elemanların birbiri ile karşılaştırılması yapılır, sıralı değilse yer değiştirir.
Karmaşıklığı Ο(n2)
Çok büyük veri kümeleri için uygun değildir
Bubble Sort
1. İle 2. elemanBu durum sıralı olduğundan değişiklik yok.
Dizinin ilk hali
2. İle 3. elaman
33 ile 27 kaşılaştırılır. Büyüklük farkı olduğundan yer değiştirilir.
3. İle 4. elaman
Bu durum sıralı olduğundan değişiklik yok.
4. İle 5. elaman
35 ile 10 karşılaştırılır. Büyüklük farkı olduğundan yer değiştirilir.
Bubble Sort - Animasyon
bubbleSort.c
Selection Sort (Seçerek Sıralama)
Dizideki minimum ve maximum değerler üzerine yapılır Dizideki en küçük eleman bulunur ve 0. pozisyona konur
Sonra ondan sonra gelen en küçük eleman bulunur ve 1. pozisyona konur Dizi sonuna gelip, sıralı oluncaya kadar devam eder
Dizinin ilk hali
14 ile dizideki min eleman olan 10 yer değiştiriyor
33 ile dizinin geri kalanından min eleman olan 14 yer değiştiriyor
27 ile dizinin geri kalanından min eleman olan 19 yer değiştiriyor
Selection Sort - Animasyon
selectionSort.c
insertion sort (ekleme – yerleştirme)
Elemanları teker teker kaydırarak, her elemanı uygun olan yere yerleştirerek yapılır Selection Sort ve Bubble sorttan daha iyidir
İlk iki eleman karşılaşırılıyor. Değişlik yok
Sonraki iki eleman 33 ile 27 karşılaştırılıyor. Yer değişiyor
Sonraki iki eleman 33 ile 10 karşılaştırılıyor. Yer değişiyor.
10 daha sonra önceki elaman 27 ile karşılaştırılıyor. Yer değiştiriyor.
10 daha sonra önceki eleman 14 ile karşılaştırılıyor. Yer değiştiriyor.
Bu döngü sona kadar devam ediyor
insertion sort
insertionsort.c
Quick Sort – Çabuk Sıralama
Parçala ve yönet (DivideAndConquer) yönetimini kullanır
Pivot bir eleman seçilir. Bundan küçük elemanlar sola, büyük elemanlar sağa sıralanır. Bunlar alt dizileri oluşturur.
Alt diziler içerisinde de aynı şekilde pivot işlemi yapılarak sıralama yapılır.
Recursive olarak devam eder.
Graph (Graf)
DR. ŞAFAK KAYIKÇI
Graf
Graf, köşelerden (düğümlerden) ve bu köşeleri bağlamak için kullanılan kenarlardan oluşan matematiksel yapılardır.
Bir G grafiği, V (G) köşelerinin kümesini, E (G) ise bu köşeleri bağlamak için kullanılan kenar kümesini temsil ettiği sıralı bir G (V, E) kümesi olarak tanımlanabilir.
5 köşeleri (A, B, C, D, E) ve altı kenarı ((A, B), (B, C), (C, E), (E, D), (D, B), (D, A)) olan G (V, E) Grafiği aşağıdaki şekilde gösterilmiştir.
Yönlendirilmiş ve Yönlendirilmemiş Graf
Yönlendirilmemiş bir grafikte, kenarlar yönlerle onlarla ilişkilendirilmez.
Yönlendirilmiş bir grafikte, kenarlar düzenli bir çift oluşturur. Kenarlar, bazı köşe A'dan diğer köşe B'ye kadar belirli bir yolu temsil eder. Düğüm A, ilk düğüm olarak adlandırılırken, B düğümü
terminal düğümü olarak adlandırılır.
Graf Terminolojisi
Yol (Path) : Bir yol, ilk düğüm U'dan bazı terminal düğüm V'ye ulaşmak için takip edilen düğümlerin dizisi olarak tanımlanabilir.
Kapalı Yol (Closed Path): İlk düğüm terminal düğümle aynıysa, yol kapalı yol olarak adlandırılır. V 0 = V N ise, bir yol kapalı olacaktır.
Çevrim(Cycle) : Bir döngü, ilk ve son köşeler dışında tekrarlanan kenar veya köşeleri olmayan bir yol olarak tanımlanabilir.
Bağlı grafik (Connected Graph): Bağlantılı grafik, V'deki her iki köşe (u, v) arasında bir yolun olduğu grafiktir.
Bağlanan grafikte izole edilmiş düğüm yoktur.
Komple Grafiği (Complete Graph) : Tam bir grafik, her düğümün diğer tüm düğümlerle bağlandığı grafiktir. Tam bir grafik, n (n-1) / 2 kenarlarını içerir, burada n, grafikteki düğümlerin sayısıdır.
Ağırlıklı Grafik (Weighted Graph): Ağırlıklı bir grafikte, her bir kenar, uzunluk veya ağırlık gibi bazı verilerle atanır.
Bir kenarın w(e) ağırlığı (maliyeti) pozitif (+) bir değerdir.
Bitişik Düğümler : İki ve n düğümü bir e kenarı yoluyla bağlanırsa, o ve n düğümleri komşular veya bitişik düğümler olarak adlandırılır.
Düğüm Derecesi : Bir düğümün derecesi, o düğüme bağlı olan kenarların sayısıdır. Derece 0 olan bir düğüme izole düğüm adı verilir.
Grafik Gösterimi - 1 - Sıralı Gösterim
Grafik Gösterimi - 2 - Bağlı Gösterim
Graf Dolaşım Algoritmaları
Grafiği dolaşmak, grafiğin tüm düğümlerini ve köşelerini incelemek anlamına gelir.
İki Standart yöntem vardır.
Genişlik Öncelikli Arama (Breadth First Search (BFS) ) Derinlik Öncelikli Arama (Depth First Search (DFS) )
Breadth First Search (BFS)
BFS, grafiği kök düğümden geçmeye başlayan ve tüm komşu düğümleri araştıran bir grafik geçiş algoritmasıdır.
Daha sonra, en yakın düğümü seçer ve keşfedilmemiş tüm düğümleri keşfeder.
Algoritma, hedefi bulana kadar en yakın düğümün her biri için aynı işlemi takip eder.
BFS Algoritmasında Kuyruk Veri Yapısı Kullanılır.
breadthFirst.c
BFS – Soru ?
Depth First Search (DFS)
Derinlik ilk arama (DFS) algoritması, G grafiğinin ilk düğümü ile başlar ve daha sonra hedef düğümü veya çocuğu olmayan düğümü bulana kadar daha derin ve derinlere gider.
Algoritma, daha sonra çıkmaz noktadan henüz tamamen keşfedilmemiş olan en son düğüme doğru geri döner.
DFS Algoritmasında Yığın Veri Yapısı Kullanılır.
depthFirst.c
DFS – Soru ?
Spanning Tree (Kapsayan (Yayılan) Ağaç)
Spanning Tree, yönlendirilmemiş ve bağlı G grafiğinin, istenen sayıda kenarın bir grafikten kaldırılmasıyla üretilen bir alt grafik ağacı olarak tanımlanabilir.
Başka bir deyişle, yayılma ağacı tüm köşeleri birbirine bağlayan bağlı ve yönlendirilmemiş bir grafiğin G döngüsel olmayan bir alt grafiğidir.
Bir grafik G, birden fazla yayılma ağacına sahip olabilir.
Greedy (açgözlü) Algoritmalar Prim's Algorithm
Kruskal's Algorithm
Prim Algoritması
İsteğe bağlı bir düğümü kök düğümü olarak seçilir.
Bu durumda, Prim'in yayılan ağacının kök düğümü olarak S düğümünü seçiyoruz. Bu düğüm isteğe bağlı olarak seçilir, böylece herhangi bir düğüm kök düğümü olabilir.
Giden kenarlar kontrol edilir ve daha düşük maliyetli olanı seçilir.
Kök düğüm S'yi seçtikten sonra, S-A ve S-C'nin sırasıyla 7 ve 8 ağırlıkta iki kenar olduğunu görüyoruz. S-A kenarını diğerinden daha az olduğu için seçiyoruz.
Prim Algoritması
S-7-A ağacı tek bir düğüm olarak kabul edilir ve ondan çıkan tüm kenarları kontrol ederiz. En düşük maliyete sahip olanı seçip, ağaca dahil ediyoruz. Bu aşamadan sonra S-7-A-3-C ağacı oluşur.
Şimdi tekrar düğüm olarak göreceğiz ve tüm kenarları tekrar kontrol edeceğiz. Ancak, yalnızca en düşük maliyetli olanı seçeceğiz. Bu durumda, C-3-D, diğer kenarların 8, 6, 4 vb.
Maliyetlerinden daha düşük olan yeni kenardır.
Prim Algoritması
Yayılan ağaca D düğümü ekledikten sonra, artık aynı maliyete sahip iki kenarımız var, yani D-2-T ve D-2-B. Böylece ikisini de ekleyebiliriz. Ancak bir sonraki adım, en düşük maliyet olarak 2. kenarı tekrar üretecek. Bu nedenle, her iki kenarı da içeren bir yayılma ağacı gösteriyoruz.
Kruskal Algoritması
Tüm kenarları artan ağırlık sırasına göre düzenleyin
Bir sonraki adım, bir dizi kenar ve ağırlık oluşturmak ve bunları artan bir ağırlık (maliyet) düzeninde ayarlamaktır.
Kruskal Algoritması
Şimdi grafiğe en az ağırlığa sahip olandan başlayarak kenarları eklemeye başlıyoruz.
En düşük maliyet 2'dir ve ilgili kenarlar B, D ve D, T'dir. Onları ekleriz. Bunları eklemek, yayılan ağaç özelliklerini ihlal etmediğinden, bir sonraki kenar seçimimize devam ediyoruz.
Sonraki maliyet 3'tür ve ilişkili kenarlar A-C ve C-D
Kruskal Algoritması
Tablodaki bir sonraki maliyet 4'tür ve bunu eklemenin grafikte bir çember yaratacağını
gözlemliyoruz. Görmezden geliriz. Bu süreçte, devre oluşturan tüm kenarları görmezden geleceğiz /
engellemeliyiz.
Ayrıca 5. ve 6. maliyetli kenarların da devre yarattığını gözlemliyoruz. Onları görmezden geliyoruz ve devam ediyoruz
7 ve 8 numaralı mevcut olan en düşük maliyetli kenarlar arasında, fiyatı 7 olan kenarı ekleyeceğiz ve artık minimum yayılma ağacına sahibiz.