diff --git a/veri-yapilari-algoritmalar/algoritma-analiz/readme.md b/veri-yapilari-algoritmalar/algoritma-analiz/readme.md index 16e385321..5de0a24d2 100644 --- a/veri-yapilari-algoritmalar/algoritma-analiz/readme.md +++ b/veri-yapilari-algoritmalar/algoritma-analiz/readme.md @@ -1 +1,40 @@ -# +# Konu Metni + +## Algoritma Analizi + +Bir problem, farklı algoritmalar kullanılarak çözülebilir. Peki bu farklı algoritmalardan hangisini kullanmalıyız nasıl karar vereceğiz? + +Algoritma analizi yaparak algoritmaları bazı kriterler kullanarak karşılaştırabiliriz. Genel olarak 3 karşılaştırma kriteri vardır: + +* Programın çalışma zamanı +* Programın çalışırken kullandığı hafıza miktarı +* Programcının, programı yazarken ne kadar süre harcadığı süre + +Duruma göre bu kriterlerden bazıları daha önem kazanabilir. Örneğin, bir programın yazılması gereken süre çok geniş ise programın çalışma zamanı ve kullandığı hafıza daha önemli hale gelebilir. + +### Programın çalışma zamanı + +Programın çalışma zamanı denilince akla ilk başta programın kaç saniyede çalıştığı gelebilir. Ancak bu göreceli bir ifadedir ve yerine göre çok farklı değerler alabilir. Bir programın kaç saniyede çalıştığı; programlama dilinden programlama diline, bilgisayardan bilgisayara hatta aynı bilgisayarda farklı zamanlarda çalıştırıldığında bile değişiklik gösterebilir. Bu sebeple çalışma zamanı **girdi sayısı ile çalışma süresinin ilişkisi** incelenerek bulunur. Bu şekilde **evrensel** bir çalışma zamanı ifadesi elde edilir. + + + +# Sorular + +1. Her programın çalışma süresi girdi sayısı arttıkça artar mı? + + Cevap: Hayır. Örneğin, bir array'de istenilen eleman anında bulunabildiği için array'in eleman sayısı artsa da istenilen elemanın bulunma süresi değişmez. + +2. Bir linked list'te istenilen bir elemanın ortalama bulunma süresi, linked list'in eleman sayısı arttıkça artar mı? + + Cevap: Evet, artar. 10 elemanlı bir linked list'te ortalama 5 elemanın dolaşılması gerekiyorsa 20 elemanlı bir linked list'te ortalama 10 elemanın dolaşılması gerekir. + +3. Bir linked list'in başına eleman eklenme süresi, eleman sayısı arttıkça artar mı? + + Cevap: Hayır, artmaz. Bir linked list'te ilk elemanın yeri bilindiğinden dolayı anında eleman eklenebilir. + + + +# Ücretsiz Kaynak + +* [Medium paylaşımı](https://medium.com/@sgoksel/algoritma-analizi-ve-big-o-notasyonu-3b7aefa8a051) linkinde bir algoritma analizi anlatımı bulabilirsiniz. + diff --git a/veri-yapilari-algoritmalar/algoritma-nedir/figures/lamba_algoritma.jpg b/veri-yapilari-algoritmalar/algoritma-nedir/figures/lamba_algoritma.jpg new file mode 100644 index 000000000..d48392d80 Binary files /dev/null and b/veri-yapilari-algoritmalar/algoritma-nedir/figures/lamba_algoritma.jpg differ diff --git a/veri-yapilari-algoritmalar/algoritma-nedir/readme.md b/veri-yapilari-algoritmalar/algoritma-nedir/readme.md index 0f6876e76..2d4ba9eab 100644 --- a/veri-yapilari-algoritmalar/algoritma-nedir/readme.md +++ b/veri-yapilari-algoritmalar/algoritma-nedir/readme.md @@ -1 +1,65 @@ -# +# Konu Metni + +## Algoritma Nedir + +Algoritma, bir problemin çözümü için yapılması gereken işlemler bütünüdür. + + + +Çok basit bir örnek olarak "**kahvaltı yapmak**" probleminin çözümü şöyledir: + +1. Başla +2. Masayı ve yemekleri hazırla +3. Yemeğini ye +4. Masayı topla +5. Bitir + +Örnekte görüldüğü gibi, bir algoritmada her adımda bir işlem yapılır ve bu işlemlerin sırası bellidir. Ayrıca, her algoritmanın bir başlangıcı ve bir bitişi vardır. + + + +### Akış Şeması + +Bir algoritmayı görselleştirmek için kullanılan bloklar bütününe **akış şeması** denir. + +Akış şemasında bloklar yapılacak işlemleri ve sorulacak soruları, oklar ise bir işlemden hangi işleme geçileceğini gösterir. Örnek bir akış şeması olarak "**bir lambanın çalışmaması**" probleminin çözüm algoritması aşağıda gösterilmiştir: + +![](https://raw.githubusercontent.com/yigitatesh/Kodluyoruz/main/figures/veri-yapilari-algoritmalar/lamba_algoritma.jpg) + +Görüldüğü gibi sorun çözülene kadar farklı işlemler yapılıyor ve sorun çözüldüğünde işlemler bitiriliyor. + + + +# Sorular + +1. Kullanıcıdan iki adet sayı isteyen, bu iki sayıyı toplayan ve toplamı gösteren programın algoritmasını yazınız. + + Cevap: + + 1. Başla + 2. A sayısını iste + 3. B sayısını iste + 4. A ve B sayısının toplamını C sayısına yaz + 5. C sayısını göster + 6. Bitir + +2. Algoritma ismi nereden gelmektedir, araştırıp yazınız. + + Cevap: El Harezmi + +3. Bir kağıda ya da Paint gibi bir program kullanarak aşağıda verilen "**bir kullanıcının sisteme girişi**" algoritmasını çiziniz. + + 1. Başla + 2. Kullanıcı adını iste + 3. Kullanıcı adı kayıtlı değil ise 2. adıma dön, kayıtlı ise 4. adıma geç + 4. Şifreyi iste + 5. Kullanıcının şifresi yanlış girildiyse 4. adıma dön, doğru girildiyse 6. adıma geç + 6. Sisteme girişe izin ver + 7. Bitir + + + +# Ücretsiz Kaynak + +* Algoritma hakkında daha çok bilgi edinmek için https://tr.wikipedia.org/wiki/Algoritma sayfasına göz atabilirsiniz. + diff --git a/veri-yapilari-algoritmalar/array/readme.md b/veri-yapilari-algoritmalar/array/readme.md index 16e385321..c9a94bfea 100644 --- a/veri-yapilari-algoritmalar/array/readme.md +++ b/veri-yapilari-algoritmalar/array/readme.md @@ -1 +1,34 @@ -# +# Konu Metni + +## Array + +Array, birden çok verinin art arda olacak şekilde tutulduğu bir veri yapısıdır. + +Örneğin; bir öğrencinin sınav notları, notların sırayla tutulduğu bir array'dir. Birden fazla ve aynı tipteki veriler tutulur. Örneğin, bir bowling maçındaki skorlar da bir skor array'idir. + +Array'ler için bilgisayarda ilk başta bir büyüklük belirlenir. Örneğin, bir öğrenci 3 sınav olacaksa 3 veri alabilecek kapasitede bir array oluşturulur. Sonra da bu boşluklara notlar yerleştirilir. Peki öğrenci bir de mazeret sınavına girmek isterse ne olur? + +Array, başta 3 kapasitesinde olduğundan dolayı 4 kapasitesine çıkarılması gerekir. Bu işlem bir kapasite artırmak olarak düşünülüp hızlı olması gerektiği söylenebilir. Ancak, 3 kapasiteli array'e eklenecek olan 4. boşluk da o array'in bitişiğinde olmalıdır. Bu kural, array'lerde hızlı bir şekilde istenilen elemana ulaşılması için gereklidir. 3 kapasiteli array'in yanında önemli bir bilgi olabileceğinden dolayı bir tane boşluk eklenmek yerine, array 4 kapasiteli ve boş olduğu bilinen bir noktaya kopyalanır ve orijinal array de silinir. Böylece, 4 kapasitesinde bir array elde edilir. + +Görüldüğü gibi bir array'e, tüm boşlukları dolu iken yeni bir veri eklemek masraflıdır. Bir avantaj olarak ise, array içindeki tüm veriler bitişik bir halde tutulduğundan dolayı istenilen sıradaki veriye çok hızlı bir şekilde ulaşılabilir. + + + +# Sorular + +1. Kapasitesi dolmuş bir array'e yeni bir veri eklerken neden array başka bir alana kopyalanır? + + Cevap: Array yapısı hafızada bitişik bir şekilde saklandığından dolayı array'in boyutu büyütülmek istendiğinde, hafızada başka bir yerde boş bir blok bulunmalı ve array elemanları oraya kopyalanmalıdır. + +2. Bir array'de sırası bilinen bir elemana ulaşmak neden çok hızlıdır? + + Cevap: Çünkü array yapısı hafızada bitişik olarak tutulur ve her elemanın nerede olduğu ilk elemanın yerine bakılarak bulunabilir. + +3. Gerçek hayattan bir array örneği veriniz. + + + +# Ücretsiz Kaynak + +* [Hackerrank problemi](https://www.hackerrank.com/challenges/arrays-ds/problem) linkine giderek verilen array'i ters çevirmeniz gereken problemi çözebilirsiniz. + diff --git a/veri-yapilari-algoritmalar/big-o/readme.md b/veri-yapilari-algoritmalar/big-o/readme.md index 16e385321..c244877cb 100644 --- a/veri-yapilari-algoritmalar/big-o/readme.md +++ b/veri-yapilari-algoritmalar/big-o/readme.md @@ -1 +1,65 @@ -# +# Konu Metni + +## Big-O Notasyonu + +Big-O notasyonu, bir algoritmanın çalışma zamanının standartlaştırılmış bir şekilde gösterilmesidir. Örneğin, bir isim array'i içinde bir ismi bulmaya çalışıyorsak ve ilk elemandan başlayıp son elemana kadar teker teker dolaşıyorsak bu işlemimizin worst case'i array uzunluğu kadar birim zaman alır. Array uzunluğuna da "n" dersek bu işlem aldığı birim zaman "n" olur. Bu sonucu Big-O notasyonu ile göstericek olursak bu işlemin zamanı "**O(n)**" olur. Bu işlem zamanına, girdi sayısı ne kadar artarsa işlem zamanı o oranda arttığı için, "**doğrusal zaman**" denir. + +Örneğin, bir array'de indeksi belirli bir elemana ulaşmaya çalışıyorsak bu işlem anında yapılır. Bu işlemin zamanı da "**O(1)**" şeklinde gösterilir ve "**sabit zaman**" denir. + +Bir isim array'inde isimler a'dan z'ye sıralı ise isimleri baştan sona aramamıza gerek yoktur. İlk önce array'in ortasına bakarız ve oradaki isim aradığımız isimden önce geliyorsa array'in sağ tarafında aramaya devam ederiz. Her seferinde bu şekilde ikiye bölerek array'in çoğu kısmını aramamış ve arama işlemini çok daha hızlandırmış oluruz. Her seferinde ikiye böldüğümüz için buradaki worst case, "2^x = n" işleminde x'in bulunmasıyla elde edilir. Bu işlemde "x" sayısı ise "log(n)" sayısına eşittir. Böylece bu işlemin zamanını "**O(log(n))**" olarak bulmuş oluruz. Bu işlem zamanına "**logaritmik zaman**" denir. + +Bir programda bir döngü ve o döngünün içinde de bir döngü varsa ve her döngü "n" iterasyon yapıyorsa bu programın zamanı "**O(nxn) = O(n^2)**" olur. Bu duruma ise "**karesiyle ilişkili zaman**" denir. + +Aşağıda bazı Big-O notasyonu kuralları verilmiştir: + +* Big-O notasyonunda katsayılar ihmal edilir. + + Örneğin, "O(2n)" ile "O(n)" aynı zaman anlamına yani "O(n)" anlamına gelmektedir. + +* Big-O notasyonunda en yüksek zamanlar seçilir, diğer zamanlar ihmal edilir. + + Örneğin, "O(n^2 + 2n + 1)" zamanı "O(n^2)" zamanına eşittir. "2n" ve "1" değerleri "n^2" değerinin yanında önemsiz kalır. Bu ihmalin sebebi de "n" sayısı büyüdükçe "n^2" sayısı çok daha büyük olacağından, bu sayının yanında "2n" ve "1" sayılarının değerinin kalmamasıdır. + + + +# Sorular + +1. Aşağıdaki fonksiyonun Big-O notasyonundaki zamanı nedir? + + ````python + def faktoriyel(x): + if x == 0: + return 1 + return x * faktoriyel(x-1) + ```` + + Cevap: Yukarıdaki faktöriyel fonksiyonunda girdi "n" ise yapılan çarpma işlemi sayısı da "n" olur. Sonuç olarak bu fonksiyonun Big-O notasyonu "O(n)" olur. + +2. Big-O notasyonu "O(n^2)" olan bir fonksiyon yazınız. + + Cevap: + + ````python + def carp(liste): + """listenin her elemanını birbiriyle çarparak tüm çarpımları toplar""" + sonuc = 0 + for i in range(len(liste)): + for j in liste[i:]: + sonuc += liste[i] * j + return sonuc + ```` + +3. En yavaş çalışacak olan Big-O notasyonu zamanı nedir? + + Cevap: O(n^n). + +# Ücretsiz Kaynak + +* [Medium paylaşımı 1](https://medium.com/kodcular/nedir-bu-big-o-notation-b8b9f1416d30) ve [Medium paylaşımı 2](https://medium.com/@sgoksel/algoritma-analizi-ve-big-o-notasyonu-3b7aefa8a051) linklerinden Big-O notasyonu hakkında bilgi edinebilirsiniz. + + + +# Ödev 4 + +O(1), O(log(n)), O(n), O(n x log(n), O(n^2), O(n^2 x log(n)), O(n^3) time complexity değerleri için birer örnek bulunuz. + diff --git a/veri-yapilari-algoritmalar/bilgi-ifade/readme.md b/veri-yapilari-algoritmalar/bilgi-ifade/readme.md index 16e385321..d210c0df0 100644 --- a/veri-yapilari-algoritmalar/bilgi-ifade/readme.md +++ b/veri-yapilari-algoritmalar/bilgi-ifade/readme.md @@ -1 +1,34 @@ -# +# Konu Metni + +## Bilginin bilgisayarda ifade edilmesi + +Bilgisayarda tüm bilgiler sadece **0** ve **1** sembollerini kullanılarak ifade edilir. Bu 0 ve 1 sembolleri ise aslında bilgisayardaki "transistör" adındaki parçaların elektrikle yüklü olup olmadıklarıdır. Bir transistörde elektrik varsa 1, elektrik yoksa 0 anlamına gelir. + + + +### Bilgisayarın ve insanların bilgiyi ifade etmesi + +Biz insanlar bilgiyi ifade etmek için birçok sembol kullanırız. Örneğin; "araba" gibi bir yazıyı ifade etmek için harfleri, "42" gibi bir sayıyı ifade etmek için sayıları, bir resmi ifade etmek için ise renkleri kullanırız. Bilgisayarlar ise aklınıza gelebilecek her bilgiyi 0 ve 1 sembollerini kullanarak ifade eder. Örneğin; bir resim bilgisayar için bir pikseller bütünüdür ve her piksel de kırmızı, yeşil ve mavi renklerinin belli oranlarda karışımından oluşur. Bilgisayar, pikselleri resimdeki sırasıyla tutar ve her pikseli de 3 tane sayı olarak tutar. + +Sonuç olarak, biz insanlar farklı türden bilgileri ifade etmek için birçok sembol ve yöntem kullanırız. Bilgisayarlar ise her türlü bilgiyi 0 ve 1 sembollerini kullanarak ifade eder. + + + +# Sorular + +1. Bilgisayarda bilgi kaç farklı sembolle ifade edilir. + + Cevap: 2 + +2. Bilgisayarda 0 ve 1 bilgisinin tutulduğu elektronik parçanın adı nedir? + + Cevap: Transistör + +3. Bilgisayarlar bir harfi nasıl ifade edebilir? Araştırınız. + + + +# Ücretsiz Kaynak + +* [Bilginin ifadesi slaytı](https://slideplayer.biz.tr/slide/2798593/) linkindeki slayta göz atabilirsiniz. + diff --git a/veri-yapilari-algoritmalar/binary-search-tree/figures/binary_search_tree.jpg b/veri-yapilari-algoritmalar/binary-search-tree/figures/binary_search_tree.jpg new file mode 100644 index 000000000..e98048a17 Binary files /dev/null and b/veri-yapilari-algoritmalar/binary-search-tree/figures/binary_search_tree.jpg differ diff --git a/veri-yapilari-algoritmalar/binary-search-tree/figures/unbalanced_binary_search_tree.jpg b/veri-yapilari-algoritmalar/binary-search-tree/figures/unbalanced_binary_search_tree.jpg new file mode 100644 index 000000000..ab8714caa Binary files /dev/null and b/veri-yapilari-algoritmalar/binary-search-tree/figures/unbalanced_binary_search_tree.jpg differ diff --git a/veri-yapilari-algoritmalar/binary-search-tree/readme.md b/veri-yapilari-algoritmalar/binary-search-tree/readme.md index 16e385321..6678e89a5 100644 --- a/veri-yapilari-algoritmalar/binary-search-tree/readme.md +++ b/veri-yapilari-algoritmalar/binary-search-tree/readme.md @@ -1 +1,159 @@ -# +# Konu Metni + +## Binary Search Tree + +Binary search tree, her noktanın en fazla iki alt noktası olan, soldaki noktanın ana noktadan küçük, sağdaki noktanın ana noktadan büyük olduğu bir ağaç yapısıdır. Eğer ağaç dengeli bir yapıya sahipse binary search algoritmasındaki gibi arama işlemleri "**log(n)**" birim zaman alır. + + + +![](https://raw.githubusercontent.com/yigitatesh/Kodluyoruz/main/figures/veri-yapilari-algoritmalar/binary_search_tree.jpg) + +Yukarıdaki ağaç dengeli bir ağaçtır. Dallanmalar neredeyse eşit olarak dağılmıştır. Dengeli bir ağacın derinliği "log(n)" olacağından dolayı yeni bir eleman ekleme işleminin time complexity'si de "**O(log(n))**" olur. + +Eğer ağaç dengeli değilse worst case durumu ortaya çıkar. Ağaca ekleme yapma, eleman arama gibi işlemlerin time complexity'si de "**O(n)**" olur. Aşağıda dengesiz bir ağaç vardır: + +![](https://raw.githubusercontent.com/yigitatesh/Kodluyoruz/main/figures/veri-yapilari-algoritmalar/unbalanced_binary_search_tree.jpg) + +Yukarıdaki ağaç yapısının bir array'den farkı yoktur ve performansı iyi değildir. Ancak ağaçları dengeli yapıda tutmak için birçok performanslı algoritma vardır ve bu problem çözülmüştür. + +**Ekstra bilgi**: Mors alfabesinin de aslında bir binary search tree yapısında olduğunu biliyor muydunuz. + + + +# Sorular + +1. Binary search tree gerçek hayatta kullanılır mı? Kullanılıyorsa nerelerde kullanılmaktadır? + + Cevap: Binary search tree performansından dolayı birçok alanda kullanılmaktadır. Programlama dillerinde derleyiciler, "map" ve "set" veri yapıları, veri tabanları bu alanlara örnek olarak verilebilir. + +2. Binary search tree'de arama yapmanın average case time complexity'si nedir? + + Cevap: O(log(n)). + +3. Binary search tree yapısının mantığını kullanan "heap sort" algoritmasını araştırınız. + + + +# Ücretsiz Kaynak + +* [Medium paylaşımı](https://tsafaelmali.medium.com/binary-search-tree-nedir-2e6fb0621d9) linkine giderek binary search tree anlatımına bakabilirsiniz. + + + +# Ödev 6 + +Binary search tree yapısını kod olarak yazınız. + +Not: Ağacın noktaları için "Node" adında bir "class" yapısı kullanabilirsiniz. + +Örnek kullanımlar aşağıdaki kod üzerinde gösterilmiştir: + +````python +# ağacın sınıf üzerinden oluşturulması +tree = BinarySearchTree() + +# sayıların ağaca eklenmesi +sayilar = [6, 15, 5, 2, 7, 8, 1, 25] +for sayi in sayilar: + tree.add_node(sayi) + +# ağacın "preorder" şeklinde yazdırılması +tree.print_tree() +```` + +Yukarıdaki ağaç yazdırıldığında şöyle bir çıktı alınmalıdır: + +```` +6 + 5 + 2 + 1 + 15 + 7 + 8 + 25 +```` + + + +Cevap: + +````python +# Class tanımlamaları +class Node: + """Ağaçtaki noktayı temsil eder""" + def __init__(self, data=None): + self.data = data + self.right = None + self.left = None + + def add_left(self, data=None): + """noktanın soluna yeni veri ekler""" + new = Node(data) + self.left = new + return new + + def add_right(self, data=None): + """noktanın sağına yeni veri ekler""" + new = Node(data) + self.right = new + return new + + +class BinarySearchTree: + """Ağacı temsil eder""" + def __init__(self, root=None): + self.root = root + + def add_node(self, new_data): + """Ağaca yeni bir eleman ekler""" + # root yoksa yeni veri ağaca root olarak eklenir + if not self.root: + self.root = Node(new_data) + return + + # ağacı dolaşmaya kökten (root) başlanır + current = self.root + while True: + # eklenecek veri zaten mevcut + if new_data == current.data: + return + # eklenecek veri sol tarafa eklenecek + elif new_data < current.data: + if not current.left: + current.add_left(new_data) + return + else: + current = current.left + # eklenecek veri sağ tarafa eklenecek + else: + if not current.right: + current.add_right(new_data) + return + else: + current = current.right + + def print_tree(self): + """Ağacı yazdırır""" + def preorder_depths(root): + # derinlik 0'dan başlar + preorder_depth(root, 0) + + def preorder_depth(root, depth): + if root: + print(" "*2*depth + str(root.data)) + preorder_depth(root.left, depth+1) + preorder_depth(root.right, depth+1) + + preorder_depths(self.root) + +# Örnek kullanım +tree = BinarySearchTree() + +sayilar = [6, 15, 5, 2, 7, 8, 1, 25] +for sayi in sayilar: + tree.add_node(sayi) + +tree.print_tree() +```` + diff --git a/veri-yapilari-algoritmalar/binary-search/readme.md b/veri-yapilari-algoritmalar/binary-search/readme.md index 16e385321..142150c8d 100644 --- a/veri-yapilari-algoritmalar/binary-search/readme.md +++ b/veri-yapilari-algoritmalar/binary-search/readme.md @@ -1 +1,49 @@ -# +# Konu Metni + +## Binary Search + +Sıralı bir array'de eleman ararken her karşılaştırmamızda baktığımız array'in yarısını eleyebiliriz. Her defasında elimizdeki array'in ortasına bakarsak aradığımız eleman ortadaki sayıdan küçükse sağ tarafı, büyükse sol tarafı direkt eleyebiliriz. Böylece çok hızlı bir şekilde arama yapabiliriz. + +Bir sözlükte kelime aradığımızı düşünelim. Sözlüğün her sayfasına teker teker bakar mıyız? Hayır, elbette bakmayız. Sözlüğün ortasını açıp ona göre hangi tarafa gideceğimize karar verebiliriz. Hatta "patika" kelimesini arıyorsak "p" harfi orta ile son kısım arasında olacağı için orta kısmın daha sağ tarafını açabiliriz. Böylece arama işlemini daha da hızlandırmış oluruz. + +### Time complexity + +Her defasında array 2'ye bölündüğü için "n" elemanlı bir dizide aramak "log(n)" birim zaman alır. Binary search algoritmasının worst case time complexity'si "**O(log(n))**" olur. + + + +# Sorular + +1. Gerçek hayattan bir binary search örneği verin. + +2. Binary search algoritmasını kod olarak yazın. + + Cevap: + + ````python + def binary_search(eleman, liste): + """binary search + aranan eleman bulunursa indeksi dönülür + bulunamazsa -1 döndürür""" + sol = -1 + sag = len(liste) + + while sag - sol > 1: + orta = (sol + sag) // 2 + if liste[orta] == eleman: + return orta + elif liste[orta] < eleman: + sol = orta + else: + sag = orta + + return -1 + ```` + +3. İnterpolation search algoritmasını araştırınız. + +# Ücretsiz Kaynak + +* [CS50 Kodluyoruz videosu](https://www.youtube.com/watch?v=jjqgP9dpD1k) linkindeki videonun 22.00 dakikasındaki kısmından searching algoritmalarının eğlenceli bir anlatımını izleyebilirsiniz. +* [Youtube videosu](https://www.youtube.com/watch?v=E6IOrZUpvSE) linkinden binary search algoritmasının animasyonunu izleyebilirsiniz. + diff --git a/veri-yapilari-algoritmalar/hash-collision/readme.md b/veri-yapilari-algoritmalar/hash-collision/readme.md index 16e385321..fa3a3fc0a 100644 --- a/veri-yapilari-algoritmalar/hash-collision/readme.md +++ b/veri-yapilari-algoritmalar/hash-collision/readme.md @@ -1 +1,94 @@ -# +# Konu Metni + +## Hash Collision + +Hash collision (hash çarpışması), hash function'ın farklı anahtarlar için aynı indeks değerini oluşturması durumudur. + +Örneğin, bir hash table'da "tak" sözcüğü ve anlamı bulunmakta. Bu hash table'a "kat" sözcüğünü eklemek istiyorum ancak aynı indeks değerini veriyor. O indekste bir veri olup olmadığına bakmadan, "kat" sözcüğünün anlamını oraya yazarsak sözlükteki "tak" sözcüğünün anlamını kaybetmiş oluruz. + +Peki bu hash collision probleminin çözümü nedir? + +**Separate chaining** (ayrı zincirleme) adlı bir yöntem kullanılabilir. Bu yöntemde, hash table'daki her kısım birer linked list olarak kullanılır. Aynı indekslere sahip olan anahtarlar, o indeksteki linked list'te tutulur. Örneğin, hash function "tak" ve "kat" sözcükleri için aynı indeksi veriyor ve şu anda hash table'da "tak" sözcüğü bulunmakta. "kat" sözcüğü hash table'a eklenirken o indeksteki linked list'in en son kısmına eklenir. Böylece bir indekste birden fazla bilgi art arda olacak şekilde tutulabilir. + +Hash collision arttıkça hash table'da ekleme, silme, arama işlemleri linked list'lerde dolaşılacağından dolayı daha uzun sürer ve hash table'ın performansı düşer. Bu yüzden bir hash function ne kadar az hash collision üretiyorsa o kadar iyidir. + + + +# Sorular + +1. Girilen anahtar değerin harflerinin ASCII değerlerini toplayıp bu toplamın 10'a bölümünden kalanı indeks olarak veren bir fonksiyon yazınız. + + Cevap: + + ````python + def hash_func(anahtar): + toplam = 0 + for harf in anahtar: + # bir karakterin ASCII değeri "ord" fonksiyonu yardımıyla bulunabilir. + toplam += ord(harf) + return toplam % 10 + ```` + +2. İlk soruda yazdığınız fonksiyonda, aynı indeks çıktısını veren iki kelime bulup yazınız. + + Örnek: "patika" ve "ak" sözcükleri "4" çıktısını veriyor. + +3. Başka yöntemlerle de hash collision sorunu çözülebilir mi? Araştırınız. + + + +# Ücretsiz Kaynak + +* [Hashing](https://yazilimdnyasi.wordpress.com/2020/02/14/hashing-nedir-veri-yapilari/) linkinde hash table ve hash collision hakkında bilgi edinebilirsiniz. + + + +# Ödev 3 + +Liste veri yapısını kullanarak "stack" ve "queue" veri yapılarını birer "class" olacak şekilde kod yazınız. + +Cevap: + +````python +class Stack: + """stack veri yapısı""" + def __init__(self, ilk_elemanlar=None): + self.veriler = [] + if ilk_elemanlar: + for i in ilk_elemanlar: + self.push(i) + + def push(self, veri): + self.veriler.append(veri) + + def pop(self): + if self.veriler: + return self.veriler.pop() + else: + return None + + def is_empty(self): + return self.veriler == [] + + +class Queue: + """queue veri yapısı""" + def __init(self, ilk_elemanlar=None): + self.veriler = [] + if ilk_elemanlar: + for i in ilk_elemanlar: + self.enqueue(i) + + def enqueue(self, veri): + self.veriler.append(veri) + + def dequeue(self): + if self.veriler: + return self.veriler.pop(0) + else: + return None + + def is_empty(self): + return self.veriler == [] +```` + diff --git a/veri-yapilari-algoritmalar/hash-function/readme.md b/veri-yapilari-algoritmalar/hash-function/readme.md index 16e385321..c288f3db5 100644 --- a/veri-yapilari-algoritmalar/hash-function/readme.md +++ b/veri-yapilari-algoritmalar/hash-function/readme.md @@ -1 +1,37 @@ -# +# Konu Metni + +## Hash Function + +Hash function, bir hash table'da anahtarları indekslere dönüştüren fonksiyondur. + +Hash table yapısında şu 3 özelliğin olması beklenir: + +1. Hash function **aynı girdiye** her zaman **aynı indeksi** vermelidir. + + Örneğin, "patika" girdisine 5 indeksi veriyorsa her "patika" anahtarı girildiğinde 5 indeksini vermelidir. + +2. Hash function **farklı girdilere** **farklı indeks** vermelidir. + + Örneğin, "patika" girdisine 5 indeksi veriyorsa başka herhangi bir girdiye 5 indeksi vermemelidir. + +3. Hash function'ın verdiği indeksler, hash table'ın değerlerinin tutulduğu **array'in sınırları içinde** olmalıdır. + + Array'in kapasitesi 10 ise, hash function en az 0 çıktısı, en fazla da 9 çıktısı vermelidir. + + + +# Sorular + +1. Kullanılabilecek bir hash function örneği veriniz. + +2. Bir hash table'ın anahtarlarının veri tipi array olabilir mi? + + Cevap: Evet, olabilir. Hash function olarak da array'in içindeki değerleri toplayan bir fonksiyon seçilebilir. + +3. Bir hash function, iki anahtar için aynı indeks değerini üretebilir. Bu duruma nasıl bir çözüm bulunabilir? + + + +# Ücretsiz Kaynak + +* [Hash function vikipedi](https://tr.wikipedia.org/wiki/Hash_fonksiyonu) linkine giderek hash function hakkında bilgi edinebilirsiniz. diff --git a/veri-yapilari-algoritmalar/hash-table/readme.md b/veri-yapilari-algoritmalar/hash-table/readme.md index 16e385321..0f6165e7d 100644 --- a/veri-yapilari-algoritmalar/hash-table/readme.md +++ b/veri-yapilari-algoritmalar/hash-table/readme.md @@ -1 +1,54 @@ -# +# Konu Metni + +## Hash Table + +Hash table, verilerin **anahtar-değer** ikilisi olarak tutulduğu ve değerlere anahtarlar üzerinden hızlıca erişilebilen bir veri yapısıdır. + +Örneğin, bir **Türkçe sözlük**, kelime-anlam ikililerinden oluşur. Burada kelimeler anahtarlardır ve anlamlar ise değerlerdir. Bir kelimenin anlamını öğrenmek için o kelimeyi bulur ve karşısında yazılmış olan anlama bakarız. Anahtar-değer ikililerinden oluştuğu için sözlükler, hash table veri yapısına örnektir. + +Peki bu anahtarlardan değerlere nasıl ulaşılıyor? + +Array'i hatırlayacak olursak her elemanın bir indeksi yani sırası vardı. Örneğin, "elma, armut, çilek" array'inde elma 1. eleman, armut 2. eleman ve çilek de 3. elemandır. Hash table denilen veri yapısını oluşturabilmek için ise anahtarları indekslere dönüştüren bir fonksiyon gerekmektedir. Bu fonksiyona **hash function** denir. Örneğin bu fonksiyon, anahtar verisinin harflerinin ASCII karakter değerlerini toplayan bir fonksiyon olabilir. Yani sözlükte "baba" kelimesinin anlamını bulurken bu harflerin ASCII değerleri toplanınca çıkan indeks sayısına gidilip kelimenin anlamı bulunabilir. Kısacası, hash table da bir array'dir ama indeksleri sadece sayı değil yazı gibi başka veri tipleri de olabilir. + +# Sorular + +1. Gerçek hayattan bir hash table veri yapısı örneği veriniz. + + Cevap: Telefon rehberi bir örnektir. İsimler anahtar, telefon numaraları da değerlerdir. + +2. Hash table yapısında iki farklı anahtar aynı indekse denk gelebilir mi? + + Cevap: Evet, denk gelebilir. Örneğin, hash function harflerin ASCII değerlerini topluyorsa "kara" ve "akar" sözcüklerinin indeks değerleri aynı olacaktır. + +3. ````python + cumle = "iki kere iki dört eder" + ```` + + Yukarıdaki "cumle" adlı değişkendeki kelimeleri ve o kelimelerin sayısını bulan bir program yazınız. + + Cevap: + + ````python + hash_table = {} + kelime_listesi = cumle.split() + + for kelime in kelime_listesi: + # kelime hash table'da varsa sayısını bir artır + if kelime in hash_table: + hash_table[kelime] += 1 + # kelime hash table'da yoksa kelimeyi sayısı 1 olacak şekilde ekle + else: + hash_table[kelime] = 1 + + print(hash_table) + ```` + + + + + +# Ücretsiz Kaynak + +* [Hackerrank problemi](https://www.hackerrank.com/challenges/ctci-ransom-note/problem) linkine tıklayarak sayfadaki problemi istediğiniz programlama dilini kullanarak çözebilirsiniz. +* Hash table hakkında daha fazla bilgi için [hash table](https://yazilimdnyasi.wordpress.com/2020/02/14/hashing-nedir-veri-yapilari/) linkine göz atabilirsiniz. + diff --git a/veri-yapilari-algoritmalar/insertion-sort/readme.md b/veri-yapilari-algoritmalar/insertion-sort/readme.md index 16e385321..040cad3cd 100644 --- a/veri-yapilari-algoritmalar/insertion-sort/readme.md +++ b/veri-yapilari-algoritmalar/insertion-sort/readme.md @@ -1 +1,58 @@ -# +# Konu Metni + +## Selection Sort + +Bir sayı dizisinin tamamının dolaşılıp en küçük elemanın başa yazıldığı, sonra da geri kalan sayıların en küçüğünün 2. eleman yerine yazıldığı ve bu şekilde dizinin sonuna kadar giden sorting algoritmasıdır. + +Örneğin, şöyle bir dizimiz olsun: dizi = [3, 1, 2] + +İlk önce tüm dizide en küçük elemanı bulup ilk eleman olan "3" sayısının yerine yazarız. Burada "1" sayısı ile "3" sayısını yer değiştiririz ve yeni dizi şöyle olur: dizi = [1, 3, 2] + +Sonra, 2. eleman ve ondan sonraki sayıların en küçüğü bulunur ve 2. elemanla yer değiştirilir. Burada "2" ile "3" sayısını yer değiştiririz. Yeni dizi şöyle olur: dizi = [1, 2, 3] + +Dizinin sonuna ulaştığımız için işlemler biter ve dizi sıralanmış olur. + +### Time complexity + +Bu sorting algoritmasında, tüm array "n" kez dolaşılır ve ilk dolaşmada "n" eleman, 2. dolaşmada ise "n-1" eleman dolaşılır. Toplam işlem sayısı "n + (n-1) + (n-2) + ... + 1" şeklinde ifade edilir ve bu ifade "(n x (n+1))/2" yani "(n^2)/2 + n/2" ifadesine eşit olur. Big-O notasyonunda katsayılardan ve küçük ifadelerden kurtuluruz ve son ifade "**O(n^2)**" şeklinde olur. + +### Space complexity + +Bildiğimiz gibi algoritmalarda ne kadar ekstra hafızanın kullanıldığı yani "space complexity" de önemlidir. Space complexity'de kullanılan ekstra hafıza yazılır. Selection sort işleminde verilen array üzerinde yani "in-place" işlemler yapıldığı için ekstra hafıza kullanılmaz. Bu yüzden, bu algoritmanın space complexity'si "**O(1)**" yani "**constant space**" olarak bulunur. + + + +# Sorular + +1. Selection sort'un best case ve worst case'leri farklı mıdır? + + Cevap: Hayır, aynıdır. Sorting işlemini durdurma mekanizması olmadığı için her seferinde "O(n^2)" olur. + +2. Sizce "O(n^2)" bir sorting algoritması için iyi bir time complexity midir? + + Cevap: O(n^2) complexity'si n sayısı arttıkça fazlaca büyür. Bu yüzden yeterince iyi değildir ve daha iyi algoritmalar vardır. + +3. Selection sort algoritmasını kod olarak yazınız. + + Cevap: + + ````python + def selection_sort(array): + for i in range(0, len(array) - 1): + # en küçük elemanı bul + en_kucuk = i + for j in range(i+1, len(array)): + if array[j] < array[en_kucuk]: + en_kucuk = j + # elemanları değiştir + array[en_kucuk], array[i] = array[i], array[en_kucuk] + return array + ```` + + + +# Ücretsiz Kaynak + +* [Video](https://www.youtube.com/watch?v=xWBP4lzkoyM) linkine giderek görüntülü bir şekilde algoritmayı görebilirsiniz. +* [Medium paylaşımı](https://medium.com/kodcular/selection-sort-algoritmas%C4%B1-nedir-484c40c9473c) linkine tıklayarak bir selection sort anlatımını bulabilirsiniz. + diff --git a/veri-yapilari-algoritmalar/linear-search/readme.md b/veri-yapilari-algoritmalar/linear-search/readme.md index 16e385321..2cabd8086 100644 --- a/veri-yapilari-algoritmalar/linear-search/readme.md +++ b/veri-yapilari-algoritmalar/linear-search/readme.md @@ -1 +1,55 @@ -# +# Konu Metni + +## Linear Search + +Linear search (doğrusal arama), bir dizide istenilen elemanın her elemanı tek tek dolaşarak aramak demektir. + +Örneğin, şöyle bir sayı listesi olsun: liste = [1, 5, 2, 8, 4] + +Bu listede "8" sayısının olup olmadığını öğrenmek için tüm elemanları tek tek dolaşırız. "1" sayısından başlarız ve 5, 2 sayılarını geçtikten sonra 8 sayısına ulaşırız. + +### Time complexity + +"n" elemanlı bir dizide arama yapıyorsak worst case'de, aradığımız elemanın dizinin sonunda olduğunda, tüm elemanları dolaşmak zorunda olduğumuzdan dolayı time complexity'si "**O(n)**" olur. Best case'de, aranılan eleman dizinin ilk elemanı olduğunda, eleman direkt olarak bulunur ve 1 birim zaman alır. Ancak bu durum nadiren görülür. + + + +# Sorular + +1. Gerçek hayattan bir linear search örneği veriniz. + +2. Sıralı bir array'de arama yapmak için linear search'ten daha iyi bir algoritma var mıdır? + + Cevap: Evet, vardır. Binary search algoritması ile array'i sürekli 2'ye bölerek çok daha hızlı bir şekilde arama yapılabilir. + +3. Linear search algoritmasını kod olarak yazınız. + + Cevap: + + Direkt olarak Python dilinin "in" keyword'ünü kullanabiliriz: + + ````python + liste = [1, 5, 2, 8, 4] + print(8 in liste) + ```` + + Veya bir "for" döngüsü ile bir fonksiyon olarak yazabiliriz: + + ````python + def ara(eleman, liste): + for i in liste: + if eleman == i: + return True + return False + + # örnek kullanım + liste = [1, 5, 2, 8, 4] + print(ara(8, liste)) + ```` + + + +# Ücretsiz Kaynak + +* [Hackerrank problemi](https://www.hackerrank.com/contests/17cs1102/challenges/1-a-linear-search) linkindeki linear search problemini çözebilirsiniz. + diff --git a/veri-yapilari-algoritmalar/linked-list-add-delete/readme.md b/veri-yapilari-algoritmalar/linked-list-add-delete/readme.md index 16e385321..fa75bd76f 100644 --- a/veri-yapilari-algoritmalar/linked-list-add-delete/readme.md +++ b/veri-yapilari-algoritmalar/linked-list-add-delete/readme.md @@ -1 +1,54 @@ -# +# Konu Metni + +## Linked List'te Eleman Ekleme/Çıkarma + +Linked list'te, sadece elemanların birbirini işaret ettiği yerlerde değişiklik yaparak bir eleman eklenebilir ve çıkartılabilir. + +Örneğin, "a -> b -> c" şeklinde 3 elemanlı bir linked list olsun. + +* Bu linked list'in sonuna bir eleman eklemek istersek şöyle yapabiliriz: + + Rastgele bir yere "d" bilgisini yazarız ve "c" elemanının "d" bilgisinin olduğu noktayı göstermesini sağlarız. Bu işlemden sonra linked list "a -> b -> c -> d" haline gelecektir. + +* "b" ve "c" elemanlarının arasına "e" bilgisini yerleştirmek için ise: + + Rastgele bir yere "e" bilgisini yazarız. "b" elemanının "e" elemanını, "e" elemanının ise "c" elemanını göstermesini sağlarız. Bu işlemlerden sonra linked list "a -> b -> e -> c" haline gelecektir. + +* "b" elemanını silmek için ise: + + "a" elemanının "c" elemanını göstermesi sağlanır ve "b" bilgisi hafızadan silinir. Böylece linked list + + "a -> c" haline gelecektir. + + + +# Sorular + +1. Bir linked list'te ilk eleman nasıl silinir? + + Cevap: Linked list'in başlangıç noktası 2. eleman yapılır ve 1. eleman hafızadan silinir. + +2. Normalde bir linked list'in sonuna eleman eklemek için tüm elemanların dolaşılması gerekir. Peki hızlı bir şekilde linked list'in sonuna eleman eklemek istiyorsak ne yapmamız gerekir? + + Cevap: Linked list'in 1. elemanının yerini tuttuğumuz gibi son elemanının yerini de tutabiliriz. Böylece son elemana da hızlı bir şekilde ulaşıp eleman ekleyebiliriz. + +3. "a -> b -> c" şeklinde bir linked list olduğunu düşünelim. a.next = b, b.next = c, c.next = None olsun. Elemanlara ".data" eklenerek de elemanın tuttuğu veriye ulaşılsın. Örneğin, "a.data" ifadesi "a" elemanının tuttuğu veriyi ifade ediyor. Bu linked list'i tersten, "c b a" şeklinde, yazdıracak bir kod yazın. + + Cevap: + + ````python + def ters_yazdir(eleman): + if eleman.next is None: + print(eleman.data) + return + + ters_yazdir(eleman.next) + print(eleman.data) + ```` + + + +# Ücretsiz Kaynak + +* [Medium paylaşımı](https://medium.com/@tolgahan.cepel/do%C4%9Frusal-veri-yap%C4%B1lar%C4%B1-2-ba%C4%9Fl%C4%B1-liste-linked-list-8e5d3d84c41f) linkinde ayrıntılı ve resimli bir linked list anlatımı bulabilirsiniz. + diff --git a/veri-yapilari-algoritmalar/linked-list-array/readme.md b/veri-yapilari-algoritmalar/linked-list-array/readme.md index 16e385321..fbc010be5 100644 --- a/veri-yapilari-algoritmalar/linked-list-array/readme.md +++ b/veri-yapilari-algoritmalar/linked-list-array/readme.md @@ -1 +1,33 @@ -# +# Konu Metni + +## Linked List vs Array + +| | Linked List | Array | +| :----------------------------------: | :----------------------------------------------------------: | :----------------------------------------------------------: | +| Sırası bilinen elemana ulaşma süresi | Bir elemana ulaşmak için o elemandan önceki her elemandan geçmek gerekir | Anında ulaşılır | +| Hafızada kapladığı yer | Her eleman içerdiği bilgiye ek olarak bir sonraki elemanın yer bilgisini tuttuğu için daha fazla yer kaplar | Her eleman sadece içerdiği bilgiyi sakladığından daha az yer kaplar | +| Hafızada saklanış biçimi | Her eleman farklı farklı yerlerde saklanabilir | Tüm elemanlar bitişik bir şekilde aynı blokta saklanır | +| Eleman ekleme ve çıkarma | Hızlı bir şekilde eleman eklenip çıkartılır | Eğer kapasite doluysa eleman eklemek için tüm array kopyalanır, eleman çıkarılıp boşluk doldurulacaksa tüm array bir boşluk kaydırılır | + + + +# Sorular + +1. Bir sayı listesi oluşturulacaksa ve bu listenin eleman sayısı sabit ise linked list mi yoksa array mi kullanmak daha mantıklı olur? + + Cevap: Array kullanmak daha mantıklı olur çünkü ekstra bir eleman eklenilmeyecek ve çıkarılmayacak. + +2. Genel olarak hangi veri yapısı daha fazla yer kaplar? + + Cevap: Linked list. + +3. Neden bir array'de sırası bilinen bir elemana linked list'ten daha hızlı ulaşılır? + + Cevap: Array'in elemanları bitişiktir ve her elemanın hafızadaki yeri ilk elemandan bulunabilir. Ancak, linked list'in elemanları hafızada farklı yerlere dağılır ve her elemanın yerini sadece ondan bir önceki eleman bilir. + + + +# Ücretsiz Kaynak + +* [Linked list vs array](https://www.youtube.com/watch?v=DyG9S9nAlUM) linkinden linked list ve array'in hız bakımından karşılaştırıldığı videoyu izleyebilirsiniz. + diff --git a/veri-yapilari-algoritmalar/linked-list/readme.md b/veri-yapilari-algoritmalar/linked-list/readme.md index 16e385321..4920b2496 100644 --- a/veri-yapilari-algoritmalar/linked-list/readme.md +++ b/veri-yapilari-algoritmalar/linked-list/readme.md @@ -1 +1,30 @@ -# +# Konu Metni + +## Linked List + +Linked list yani **bağlı liste**, ilk elemanı belli olan ve her elemanın, ondan sonraki elemanın yerini bildiği bir veri yapısıdır. Yani 1. eleman 2. elemanın, 2. eleman da 3. elemanın nerede olduğunu bilir. Böylece veri elemanları arasında bir bağ kurulmuş olup bir liste oluşturulabilir. Örneğin, okul sırasında kollarımızı öndeki kişinin omuzlarına koyardık. Herkes bir öndeki kişinin omuzlarına kollarını koyarsa bir linked list oluşmuş olur. Linked list'te sondaki elemanın bir yere işaret etmesi gerekmediği gibi en öndeki öğrencinin de kolunu uzatması gerekmez. + +Linked list'in avantajlarından biri, array gibi hafızada bitişik bir şekilde tutulması gerekmemesidir. Her eleman farklı farklı yerlerde olabilir çünkü her eleman bir sonraki elemanın yerini bilir. + + + +# Sorular + +1. Toplamda 3 elemanı olan bir linked list'in kaç elemanı bir sonraki elemanın yerini bilir? + + Cevap: 2 eleman çünkü sonuncu elemanın bir yeri bilmesi gerekmez. + +2. Bir linked list'te 5. elemana direkt ulaşabilir miyiz? + + Cevap: Hayır. 5. elemana ulaşmak için 4. elemana, 4. elemana ulaşmak için 3. elemana ulaşmak gerekir. Yani 1. elemandan sırayla ilerleyerek 5. elemana 4 hamlede ulaşılabilir. + +3. Linked list'in başka çeşitleri var mıdır? Araştırınız. + + + +# Ücretsiz Kaynak + +* [Hackerrank problemi](https://www.hackerrank.com/challenges/print-the-elements-of-a-linked-list/problem) linkine tıklayarak sayfadaki problemi istediğiniz programlama dilini kullanarak çözebilirsiniz. + + + diff --git a/veri-yapilari-algoritmalar/merge-sort/figures/merge_sort.PNG b/veri-yapilari-algoritmalar/merge-sort/figures/merge_sort.PNG new file mode 100644 index 000000000..f9d95e85e Binary files /dev/null and b/veri-yapilari-algoritmalar/merge-sort/figures/merge_sort.PNG differ diff --git a/veri-yapilari-algoritmalar/merge-sort/readme.md b/veri-yapilari-algoritmalar/merge-sort/readme.md index 16e385321..16ab80fc1 100644 --- a/veri-yapilari-algoritmalar/merge-sort/readme.md +++ b/veri-yapilari-algoritmalar/merge-sort/readme.md @@ -1 +1,67 @@ -# +# Konu Metni + +## Merge Sort + +Merge sort, hız kazandırmak için "**parçala-fethet**" (divide and conquer) yöntemi kullanan bir sorting algoritmasıdır. İlk önce array 2'ye bölünerek küçük array'lere ayrılır. Sonra da bu array'ler sıralanarak birleştirilir. + + + +![](https://raw.githubusercontent.com/yigitatesh/Kodluyoruz/main/figures/veri-yapilari-algoritmalar/merge_sort.PNG) + +Yukarıda görüldüğü gibi array 2'ye bölünerek 1 elemanlı array'lere ayrılmıştır. Ondan sonra ise sıralanarak birleştirme işlemi yapılmıştır. Örneğin, sol orta kısımda 38 ve 27 sayısı birleştirilmiş, [27, 38] şeklinde bir array elde edilmiştir. Sonra bu 2 elemanlı array'ler de sıralanarak birleştirilir. Buradaki avantaj, sıralanmış küçük array'lerin sıralanarak birleştirilmesidir. Zaten sıralı olduğu bilinen array'lerin karşılaştırılması daha kolaydır. + +### Time complexity + +İlk önce küçük array'ler birleştirilirken yapılan karşılaştırma sayılarını hesaplayalım. Bu sayı; 1 elemanlı array'ler için 4, 2 elemanlı array'ler için 6 ve 4 elemanlı array'ler için 7'dir. Yukarıdaki array'in eleman sayısına "n" diyelim. Worst case'i hesapladığımızdan dolayı karşılaştırma sayısı olarak "7 = n-1" yani "n" diyebiliriz. Peki kaç array sırasını karşılaştırıyoruz. Her seferinde array'i 2'ye böldüğümüz için bu sayı "2^x = n" yani "log(n)" şeklinde çıkacaktır. Yukarıdaki örnekte görüldüğü gibi 7 elemanlı bir array'de bu sayı "log(7)" yani yukarı yuvarlandığında "3" olacaktır. "log(n)" array serisi karşılaştırılmakta ve her karşılaştırma "n" birim zaman almaktadır. Sonuç olarak, merge sort algoritmasının worst case time complexity'si "**O(n x log(n))**" şeklinde bulunur. + + + +# Sorular + +1. "O(n x log(n))" time complexity'si, "O(n^2)" ile karşılaştırıldığında yeterince iyi midir? + + Cevap: Evet. Özellikle n sayısı büyüdüğünde çok büyük farklar olduğu görülecektir. Log(n) fonksiyonu çok yavaş bir şekilde arttığından ve sayı büyüdükçe artma şiddeti azaldığından dolayı "O(n x log(n))" performansı "O(n)" performansına yakındır. + +2. Merge sort algoritmasının space complexity'si nedir? Araştırınız. + + Cevap: O(n). + +3. Merge sort algoritmasını kod olarak yazınız. + + Cevap: + + ````python + def merge_sort(array): + """merge sort""" + if len(array) > 1: + orta = len(array) // 2 + sol = merge_sort(array[:orta]) + sag = merge_sort(array[orta:]) + return merge(sol, sag) + else: + return array + + def merge(sol, sag): + """iki array'i sıralayarak birleştirir""" + sirali_array = [] + + while len(sol) > 0 and len(sag) > 0: + if sol[0] <= sag[0]: + sirali_array.append(sol.pop(0)) + else: + sirali_array.append(sag.pop(0)) + + while len(sol) > 0: + sirali_array.append(sol.pop(0)) + while len(sag) > 0: + sirali_array.append(sag.pop(0)) + + return sirali_array + ```` + + + +# Ücretsiz Kaynak + +* [Video](https://www.youtube.com/watch?v=JSceec-wEyw) linkine tıklayarak merge sort algoritmasını görüntülü bir şekilde görebilirsiniz. + diff --git a/veri-yapilari-algoritmalar/queue/readme.md b/veri-yapilari-algoritmalar/queue/readme.md index 16e385321..42a12d238 100644 --- a/veri-yapilari-algoritmalar/queue/readme.md +++ b/veri-yapilari-algoritmalar/queue/readme.md @@ -1 +1,22 @@ -# +# Konu Metni + +## Queue + +Queue (**sıra**), bir tarafından sadece eleman eklenebilen ve diğer tarafından sadece eleman çıkartılabilen bir veri yapısıdır. + +Örneğin, market sırası bir queue yapısıdır. Market sırasına ilk giren kişi ilk ödemesini yapar ve sıradan çıkar, son giren kişi ise önündeki kişileri beklemek durumundadır. Queue yapısında bir elemanın sıraya eklenmesine **enqueue**, bir elemanın sıradan çıkarılmasına **dequeue** denir. İlk sıraya giren kişi ilk önce sıradan çıkacağından dolayı queue, ilk giren ilk çıkar anlamına gelen "**First in first out**", kısaca "**FIFO**" bir yapıdır. + +Queue veri yapısının kullanışlı olduğu yerler, bir sıranın olduğu yerlerdir. Örneğin, internetten bir dosya indirirken aynı anda birçok kişi o siteden dosya indiriyorsa kullanıcı bir dosya indirme sırasına sokulabilir. + +# Sorular + +1. Gerçek hayattan bir queue veri yapısı örneği veriniz. +2. [Hackerrank problemi](https://www.hackerrank.com/challenges/30-queues-stacks/problem) linkine tıklayarak girilen kelimenin bir [palindrom](https://tr.wikipedia.org/wiki/Palindrom) olup olmadığını queue ve stack kullanarak bulmanız gereken problemi çözebilirsiniz. +3. Double-ended queue (çift taraflı queue) nedir? Araştırınız. + + + +# Ücretsiz Kaynak + +* [Medium paylaşımı](https://medium.com/@tolgahan.cepel/do%C4%9Frusal-veri-yap%C4%B1lar%C4%B1-4-kuyruk-queue-dcbd07e8ba77) linkinde ayrıntılı ve resimli bir queue anlatımı bulabilirsiniz. + diff --git a/veri-yapilari-algoritmalar/quick-sort/figures/quick_sort.jpg b/veri-yapilari-algoritmalar/quick-sort/figures/quick_sort.jpg new file mode 100644 index 000000000..50eeec0eb Binary files /dev/null and b/veri-yapilari-algoritmalar/quick-sort/figures/quick_sort.jpg differ diff --git a/veri-yapilari-algoritmalar/quick-sort/readme.md b/veri-yapilari-algoritmalar/quick-sort/readme.md index 16e385321..980c59da9 100644 --- a/veri-yapilari-algoritmalar/quick-sort/readme.md +++ b/veri-yapilari-algoritmalar/quick-sort/readme.md @@ -1 +1,96 @@ -# +# Konu Metni + +## Quick Sort + +Quick sort, array'den her seferinde bir pivot eleman seçilip, pivot elemandan küçük olan sayıları sol array'e, pivot elemandan büyük olan sayıları sağ array'e konulduğu ve bu işlemin sağ ve sol array için tekrarlandığı sorting algoritmasıdır. + + + +![](https://raw.githubusercontent.com/yigitatesh/Kodluyoruz/main/figures/veri-yapilari-algoritmalar/quick_sort.jpg) + +Yukarıda görüldüğü gibi bir pivot eleman seçilir ve bu elemana göre array 2'ye bölünür. + + + +### Time complexity + +Quick sort algoritması da "**parçala-fethet**" yöntemini kullanır. Array'in eleman sayısına "n" diyelim. Her array 2'ye bölündüğünde yaklaşık "n" tane karşılaştırma yapılır. Array'lerin her seferinde tam olarak 2'ye bölündüğünü varsayarsak toplam bölünme sayısı "log(n)" olacaktır ve bu da "average case" olacaktır. Sonuç olarak, quick sort algoritmasının **average case** time complexity'si "**O(n x log(n))**" olur. + +Peki worst case'i nedir? Her seferinde array'in tüm elemanlarının sağ tarafa bölündüğünü düşünelim. Her seferinde pivot elemana göre sıralama yapıldığı için pivot ortada ve geri kalan array sağda kalacaktır. Bu durumda toplam "n" tane array bölünmesi yapılacak ve her bölünmede "n" karşılaştırma olacağından **worst case** time complexity'si "**O(n^2)**" olacaktır. Ancak genelde bu durum gözlenmediğinden dolayı bu algoritmanın genel performansı "**O(n x log(n))**" olacaktır. + + + +# Sorular + +1. Quick sort algoritmasında neden worst case yerine average case'i tercih ederiz? + + Cevap: Worst case durumunun görülme olasılığı çok düşük olduğundan ve genelde average case performansı görüldüğünden dolayı quick sort için average case tercih edilir. + +2. Neden quick sort genelde merge sort'tan daha hızlıdır? + + Cevap: Average case time complexity'leri aynıdır ancak quick sort algoritmasının katsayısı daha düşüktür. Biz katsayıları Big-O notasyonunda ihmal etsek de pratikte katsayılar da fark yaratabilir. + +3. Quick sort algoritmasını kod olarak yazınız. + + Cevap: + + ````python + def quick_sort(array): + """quick sort algoritması""" + if len(array) < 2: + return array + # pivot seçimi + pivot = array.pop() + sol = [] + sag = [] + + # pivot elemana göre sol ve sağ array'leri oluştur + for i in array: + if i < pivot: + sol.append(i) + else: + sag.append(i) + # recursive quick sort işlemi + return quick_sort(sol) + [pivot] + quick_sort(sag) + ```` + + + +# Ücretsiz Kaynak + +* [Video](https://www.youtube.com/watch?v=XE4VP_8Y0BU) linkinden quick sort algoritmasının anlatımını izleyebilirsiniz. +* [Video](https://www.youtube.com/watch?v=es2T6KY45cA) linkinden quick sort ve merge sort'un karşılaştırıldığı bir animasyonu izleyebilirsiniz. + + + +# Ödev 5 + +Elimizde tam sayılardan oluşan ve sayı çeşidinin ve aralığının çok fazla olmadığı, aynı sayıların da bulunduğu ve en küçük sayı ile en büyük sayı arasında çok büyük bir farkın olmadığı, bir array olduğunu düşünelim. Bu array'i en hızlı şekilde nasıl sıralayabiliriz? + +Bu tip senaryolarda kullanılabilen "count sort" algoritmasını araştırınız ve kod olarak yazınız. + +Cevap: + +````python +def count_sort(array): + """count sort""" + # array'deki en küçük ve en büyük elemanları bulalım + kucuk = min(array) + buyuk = max(array) + + # elemanları ve sayılarını tutacak olan hash table'ı oluşturalım + hash_table = {i: 0 for i in range(kucuk, buyuk + 1)} + for i in array: + hash_table[i] += 1 + + # hash table'daki elemanları sayıları kadar olacak şekilde + # sırasıyla array'e "in-place" olarak yerleştirelim + i = 0 + for j in range(kucuk, buyuk + 1): + for _ in range(hash_table[j]): + array[i] = j + i += 1 + + return array +```` + diff --git a/veri-yapilari-algoritmalar/ram-model/readme.md b/veri-yapilari-algoritmalar/ram-model/readme.md index 16e385321..7b4edb63c 100644 --- a/veri-yapilari-algoritmalar/ram-model/readme.md +++ b/veri-yapilari-algoritmalar/ram-model/readme.md @@ -1 +1,36 @@ -# +# Konu Metni + +## RAM Modeli + +Hayali bir bilgisayar oluşturalım ve her algoritmayı bu bilgisayarla analiz edebilelim. Bu bilgisayarın analizleri ise evrensel ve genelleştirilebilir analizler olsun. Bu makineye de RAM (Random Access Machine) adını verelim. + +RAM'in özellikleri şunlardır: + +1. Basit işlemler (toplama, çıkarma gibi) **1 birim zaman alır**. +2. Döngüler **iterasyon sayısı x işlem sayısı** kadar zaman alır. Burada işlem sayısı, bir döngüdeki işlem sayısıdır. +3. Hafızadan okuma işlemi de **1 birim zaman alır**. + +RAM'i kullanarak algoritmaları analiz edebileceğiz. + + + +# Sorular + +1. RAM'de bir çarpma işlemi kaç birim zaman alır? + + Cevap: 1 birim zaman alır. + +2. Bir programın 5 iterasyona sahip bir döngü içerdiğini ve her iterasyonda 3 işlem yaptığını düşünelim. Bu programın çalışması kaç birim zaman alır? + + Cevap: 5 x 3 = 15 birim zaman alır. + +3. Bir sayının 3. üssünün alınması işlemi kaç birim zaman alır? + + Cevap: 2 üzeri 3'ün hesaplanmasını düşünelim. Önce 2 ile 2 çarpılır ve 4 bulunur. Bir çarpma işlemi gerçekleşti. Sonra ise 4 ile 2 çarpılır ve 8 bulunur. 2. çarpma işlemi gerçekleşti. İşlem tamamlandı ve 2 çarpma işlemi gerçekleşti. O zaman bu işlem 2 birim zaman alır. + + + +# Ücretsiz Kaynak + +* [Algoritma analizleri](http://cagataykiziltan.net/programin-calisma-hizi-ve-algoritma-verimliligi/zaman-karmasikligi-ve-buyuk-o-notasyonu-time-complexity-and-big-o-notation/) linkine giderek algoritma analizini inceleyebilirsiniz. + diff --git a/veri-yapilari-algoritmalar/recursion/readme.md b/veri-yapilari-algoritmalar/recursion/readme.md index 16e385321..1e0095112 100644 --- a/veri-yapilari-algoritmalar/recursion/readme.md +++ b/veri-yapilari-algoritmalar/recursion/readme.md @@ -1 +1,141 @@ -# +# Konu Metni + +## Recursion + +Bir problem kendi içinde tekrar ediyorsa bu problem "**recursive**" yani "**özyinelemeli**" bir problemdir. Örneğin, bir **üs alma problemini** ele alalım. 2 sayısının 3. üssünü alacağımızı düşünelim. Bu üs alma problemini, 2^3 = 2 x 2^2 şeklinde açabiliriz. Ve bu problemi de, 2 x 2^2 = 2 x 2 x 2^1 şeklinde açabiliriz. 2^1 = 2 olduğundan dolayı sonuç "2 x 2 x 2" işleminin sonucu yani 8 olur. Üs alma işleminde, gördüğümüz gibi çarpma işlemi yineleniyor. Böylece bu problem bir "özyinelemeli" yani "**kendi içinde tekrar eden**" bir problem oluyor. + +Örneğin, 2 aynayı karşı karşıya tutup bir aynaya baktığımız zaman yansıma görüntüsünün sonsuza kadar gittiğini görürüz. İşte burada da bir aynadan diğer aynaya görüntü tekrar tekrar yansıdığından dolayı sonsuza kadar tekrar eden bir yansıma döngüsü oluşmaktadır. + +# Sorular + +1. 2 sayısının istenilen üssünü alan "recursive" bir programı, Python ya da istediğiniz başka bir programlama dilinde yazınız. + + Cevap: + + ````python + def ussunu_al(x): + # base case + if x == 0: + return 1 + + return ussunu_al(x-1) * 2 + ```` + + + +2. Özyinelemeli fonksiyonlarda "base case" nedir ve neden gereklidir? Araştırınız. + + Cevap: Bir özyinelemeli fonksiyonda Base case yoksa o fonksiyon çalıştırıldığında bilgisayarın hafızası dolana kadar ya da programlama dilinin sınırı aşılana kadar çalışır. Sonra da program kapanır. Base case bir özyinelemeli fonksiyonun belli bir duruma durdurulması için gereklidir. + +3. [Fibonacci problemi](https://www.hackerrank.com/challenges/ctci-fibonacci-numbers/problem) linkine giderek istenilen Fibonacci sayısını veren fonksiyonu recursion kullanarak yazınız. + + + +# Ücretsiz Kaynak + +* [Youtube videosu](https://www.youtube.com/watch?v=Mv9NEXX1VHc) linkine giderek recursion anlatımını izleyebilirsiniz. + + + +# Ödev 1 + +Bu ödevde, girilen yazının harflerinin ASCII değerlerini ikili sistemde yazacak bir program yazmanız istenmekte. Örneğin; "BABA" yazısı girildiyse çıktı "1000010 1000001 1000010 1000001" olmalıdır. + +Örneğin; + +````python +print(decimal_to_binary("B")) +```` + +Kodu çalıştırıldığında şu çıktı verilmeli: + +````python +1000010 +```` + +Alttaki kod çalıştırıldığında ise: + +````python +text_to_binary("BABA") +```` + +Şu çıktı verilmeli: + +````python +1000010 1000001 1000010 1000001 +```` + +Not: Öncelikle verilen ondalık sayıyı ikili sistem sayısına dönüştüren ve bu sayıyı string olarak dönen bir fonksiyon yazın. Bundan sonra ise verilen yazının harflerinin ASCII değerlerini ikili sistemde yazacak fonksiyonu yazın. + +Cevap: + +````python +def decimal_to_binary(x): + """girilen ondalık sayıyı ikili sisteme dönüştürür""" + if x == 0: + return "0" + + sonuc = "" + # bölüm 0 olduğunda dur + while x > 0: + kalan = x % 2 + x = x // 2 + # kalanı sonuca ekle + sonuc = str(kalan) + sonuc + + return sonuc + +def text_to_binary(yazi): + """girilen yazının harflerini ikili sistemde yazdırır""" + for harf in yazi: + ascii_deger = ord(harf) + ikili_deger = decimal_to_binary(ascii_deger) + print(ikili_deger, end=" ") + +# örnek kullanım +text_to_binary("BABA") +```` + + + +# Ödev 2 + +Verilen listeler listesini tamamen düz bir listeye çevirecek bir program yazınız. + +Örneğin, verilen listenin bir elemanı sayı diğer bir elemanı ise bir listeler listesi olabilir. + +Örnek olarak alttaki kod çalıştırıldığında: + +````python +liste = [[1, [4, 5]], [[[12, 13], 14]], 4, [3, 2], "a"] + +print(duzlestir(liste)) +```` + +Verilen çıktı şöyle olmalıdır: + +````python +[1, 4, 5, 12, 13, 14, 4, 3, 2, 'a'] +```` + +Cevap: + +````python +def duzlestir(liste): + """verilen bir iç içe listeyi tamamen düz bir listeye dönüştürür""" + duz_liste = [] + + for i in liste: + if type(i) == list: + # extend metodu sayesinde liste, bir liste ile genişletilebilir + duz_liste.extend(duzlestir(i)) + else: + duz_liste.append(i) + + return duz_liste + +# Örnek kullanım +lst = [[1, [4, 5]], [[[12, 13], 14]], 4, [3, 2], "a"] +print(duzlestir(lst)) +```` + diff --git a/veri-yapilari-algoritmalar/sayi-sistem/readme.md b/veri-yapilari-algoritmalar/sayi-sistem/readme.md index 16e385321..dd7527772 100644 --- a/veri-yapilari-algoritmalar/sayi-sistem/readme.md +++ b/veri-yapilari-algoritmalar/sayi-sistem/readme.md @@ -1 +1,48 @@ -# +# Konu Metni + +## Sayı Sistemleri + +Biz insanlar, sayı sistemi olarak **ondalık sistemi** kullanırız. Bu sistemde 10 tane farklı sembol vardır. Bilgisayarlar ise insanlardan farklı olarak **ikili sayı sistemi** kullanır ve bu sistemde sadece 2 sembol vardır. Bu iki sembol ise **0** ve **1**'dir. Biz her sayıyı 10 tane rakam kullanarak nasıl ifade ediyorsak, bilgisayarlar da sadece 2 tane rakam kullanarak ifade eder. + + + +Bir sayı yazdığımızda, her rakam bir **basamağa** aittir. Örneğin; "**240**" sayısını yazdığımızda 0 rakamı birler basamağına, 4 rakamı onlar basamağına, 2 rakamı ise yüzler basamağına aittir. Aslında bir sayıyı anlarken yaptığımız şey her rakamı basamağıyla çarpıp hepsini toplamaktır. Yani "240" sayısı "**2x100 + 4x10 + 0x1**" şeklinde de anlaşılabilir. Bu işlemin sonucu ise elbette "240" olacaktır. + + + +Ondalık sistemde, basamaklar 1'den başlar ve toplamda 10 tane kullanılabilecek rakam olduğundan dolayı 10 ile çarpılarak (birler, onlar, yüzler, binler basamağı şeklinde) devam eder. İkili sistemde ise 0 ve 1 olmak üzere 2 tane rakam vardır. Bu yüzden de basamaklar yine 1'den başlar ancak 2 ile çarpılarak (birler, ikiler, dörtler, sekizler basamağı şeklinde) devam eder. + +Örnek olarak "**1101**" sayısını ikili sayı sisteminde ele alalım. Basamaklarına göre açılım yapacak olursak "**1x8 + 1x4 + 0x2 + 1x1**" şeklinde açarak bu sayının ondalık sistemde hangi sayıya denk geldiğini bulabiliriz. İşlem yapıldığında sayı ondalık sistemde "**13**" oluyor. Gördüğümüz gibi ikili sistemdeki "1101" sayısı ondalık sistemde "13" sayısına denk geliyor. Bu sayıların içerdikleri bilgi aynı fakat farklı sayı sistemlerinde yazıldıkları için farklı görünüyorlar. + + + +### Ondalık sistem ve ikili sistem arasında dönüşümler + +Peki "13" sayısını ondalık sistemden ikili sisteme nasıl dönüştürebiliriz? Ondalık sayı sisteminde basamakları bulmak için sayıyı 10'a böleriz ve bölümlerden kalanlar bize basamakları verir. + +"13" sayısında bu işlemi yapalım. 13'ü 10'a bölünce bölüm 1 ve kalan 3 çıkar. Demek ki 3 birler basamağında. Bölüm olan 1'i 10'a bölünce bölüm 0 ve kalan 1 çıkar. Demek ki onlar basamağında 1 var. Bölüm 0 olduğu için işlemi bitirir ve sayıları basamaklarına yazarız. Sonuç olarak "13" sayısını elde ederiz. + +"13" sayısını ikili sisteme çevirmek için aynı işlemleri yapmalıyız ancak 10 sayısına değil de 2 sayısına bölmeliyiz. İşlemleri yapalım. 13'ü 2'ye bölünce bölüm 6 ve kalan 1 çıkar. Birler basamağında 1 var. 6'yı 2'ye bölünce bölüm 3 ve kalan 0 çıkar. İkiler basamağında 0 var. 3'ü 2'ye bölünce bölüm 1 ve kalan da 1 çıkar. Dörtler basamağında 1 var. 1'i 2'ye bölünce bölüm 0 ve kalan 1 çıkar. Sekizler basamağında da 1 var. Bölüm 0 olduğundan işlemleri bitiririz ve sonuç ise "1101" çıkar. + + + +# Sorular + +1. Ondalık sistemde yazılmış "58" sayısı, ikili sistemde hangi sayıya denktir? + + Cevap: 111010 + +2. İkili sistemde yazılmış "1001101" sayısı, ondalık sistemde hangi sayıya denktir? + + Cevap: 77 + +3. Bize "1011" sayısının verildiğini düşünelim. Bu sayının ondalık sistemde mi yoksa ikili sayı sisteminde mi yazıldığını kesin olarak söyleyebilir miyiz? + + Cevap: Sayı 0 ve 1 rakamlarından oluşmaktadır. Ancak, bu iki rakam hem ondalık sistemde hem de ikili sistemde bulunmaktadır. Bu yüzden kesin olarak hangi sistemde yazıldığını söyleyemeyiz. + + + +# Ücretsiz Kaynak + +* [Hackerrank problemi](https://www.hackerrank.com/challenges/30-binary-numbers/tutorial) linkine tıklayarak sayfadaki problemi istediğiniz programlama dilini kullanarak çözebilirsiniz. + diff --git a/veri-yapilari-algoritmalar/sayisal-olmayan/readme.md b/veri-yapilari-algoritmalar/sayisal-olmayan/readme.md index 16e385321..981a58a51 100644 --- a/veri-yapilari-algoritmalar/sayisal-olmayan/readme.md +++ b/veri-yapilari-algoritmalar/sayisal-olmayan/readme.md @@ -1 +1,31 @@ -# +# Konu Metni + +## Sayısal Olmayan Bilgilerin İfadesi + +Sayısal olmayan bilgileri, bir yazı gibi, biz insanlar harfleri kullanarak belirtiriz. Ancak bilgisayarlar, her bilgi gibi yazı bilgisini de 0 ve 1 rakamlarını kullanarak ifade eder. Peki bu nasıl mümkün olabiliyor? + +Bilgisayar, her harfi ya da karakteri farklı bir sayı olarak ifade eder. Örneğin; "1000001" sayısı aslında ondalık sistemde "65" sayısını ifade eder. Ancak, biz bu sayının bir yazı karakterini ifade ettiğini biliyorsak "1000001" sayısının "A" harfini ifade ettiğini söyleyebiliriz. Aynı şekilde ondalık sistemde "66" sayısına denk gelen "1000010" sayısı da "B" harfini ifade eder. + +Bir yazı ise bu karakterlerin art arda sıralanmasından oluşur. Örneğin; "BABA" kelimesini yazmak için "B" ve "A" anlamına gelen ikili sayılar sıralanmalıdır. "1000010 1000001 1000010 1000001" sayı dizisi bir yazı olarak "BABA" kelimesine denktir. + + + +# Sorular + +1. ASCII karakter setini araştırınız. Karakterleri inceleyiniz ve bu setin kaç karakterden oluştuğunu yazınız. + + Cevap: ASCII karakter seti 128 karakterden oluşmaktadır. Genişletilmiş ASCII karakter seti ise 256 karakterden oluşur. + +2. ASCII karakter kodları ile "patika" kelimesini yazınız. + + Cevap: 1110000 1100001 1110100 1101001 1101011 1100001 + +3. Dünyada çok sayıda yazı karakteri vardır ve bu karakterlerin hepsini ASCII karakter setine sığdırmak imkansızdır. Örneğin, bir Türkçe karakter olan "ş" harfi ASCII karakter setinde bulunmaz. Peki bu probleme nasıl bir çözüm bulunmuştur? Araştırınız. + + + +# Ücretsiz Kaynak + +* [Hackerrank problemi](https://www.hackerrank.com/contests/codejam2/challenges/super-easy-ascii) linkine tıklayarak sayfadaki problemi istediğiniz programlama dilini kullanarak çözebilirsiniz. +* [Karakter kodlamaları](https://python-istihza.yazbel.com/karakter_kodlama.html) linkinde karakter kodlamalarının detaylı anlatımına ulaşabilirsiniz. + diff --git a/veri-yapilari-algoritmalar/searching/readme.md b/veri-yapilari-algoritmalar/searching/readme.md index 16e385321..d928aaca7 100644 --- a/veri-yapilari-algoritmalar/searching/readme.md +++ b/veri-yapilari-algoritmalar/searching/readme.md @@ -1 +1,22 @@ -# +# Konu Metni + +## Searching + +Searching (arama), bir dizide belirli bir elemanın aranması işlemidir. Bu işlemin hızı algoritma kullanımına göre çok fark edebilir. + +Searching işlemi çok sık kullanılan bir işlemdir. Bir veri tabanında istediğimiz veriyi bulma, bilgisayarımızda bir dosya arama, Google'da arama yapma gibi birçok örnek verilebilir. + + + +# Sorular + +1. Gerçek hayattan bir searching örneği veriniz. +2. Alfabetik olarak sıralanmış bir sözlükte mi yoksa tüm kelimelerin yerlerinin rastgele olduğu bir sözlükte mi arama yapmak daha kolaydır? Açıklayınız. +3. Searching algoritmalarını araştırınız. + + + +# Ücretsiz Kaynak + +* [Searching algoritmaları](https://medium.com/@enesates03/arama-algoritmalar%C4%B1-search-algorithms-nedir-7c8be09d541a) linkine giderek searching nedir ve hangi algoritmalar vardır inceleyebilirsiniz. + diff --git a/veri-yapilari-algoritmalar/sorting/readme.md b/veri-yapilari-algoritmalar/sorting/readme.md index 16e385321..7adef65c7 100644 --- a/veri-yapilari-algoritmalar/sorting/readme.md +++ b/veri-yapilari-algoritmalar/sorting/readme.md @@ -1 +1,46 @@ -# +# Konu Metni + +## Sorting + +Sorting (sıralama), bir eleman dizisini belirli bir sıralama ölçütüne göre sıralamaktır. Bu sıralama ölçütleri; artan, azalan, alfabetik, kelimenin uzunluğuna göre artan gibi farklı ölçütler olabilir. Örneğin; Bir Türkçe sözlükte kelimeler, insanların kelimeleri kolay bulabilmesi için alfabetik olarak sıralanmıştır. + +### Sorting neden kullanılır? + +* Bir array'i sıralarsak eleman arama işlemi hızlanır. Hatırladığımız gibi array'i ikiye böle böle bir elemanı daha hızlı bir şekilde arayabiliriz. +* Mode ve kartiller gibi bazı istatistik terimleri sıralama yapmadan bulunamaz. +* Sorting yaptığımızda, array'deki en yakın değerleri taşıyan veriler yan yana gelir. Böylece, herhangi bir veriye en yakın olan veriler bulunabilir. + + + +# Sorular + +1. Gerçek hayattan bir sorting örneği veriniz. + +2. Bubble sort algoritmasını araştırınız ve algoritmayı kod olarak olarak yazınız. + + Cevap: + + ````python + def bubble_sort(array): + siralandi = False + # bir sayı değişim işlemi yapılmazsa array sıralanmış demektir + # o zaman sıralama işlemi bitirilir + while not siralandi: + siralandi = True + for i in range(len(array) - 1): + if array[i] > array[i+1]: + array[i], array[i+1] = array[i+1], array[i] + siralandi = False + + return array + ```` + +3. Bubble sort'un worst case Big-O notasyonunu hesaplayınız. + + Cevap: En kötü senaryoda n elemanlı bir array'i "n" defa dolaşır. Her dolaşmada da "n" tane eleman geçiliyorsa Big-O notasyonu "O(n^2)" olur. + +# Ücretsiz Kaynak + +* [Sorting algoritmaları](https://www.halildurmus.com/2021/02/22/siralama-algoritmalari-sorting-algorithms/) linkinden farklı sorting algoritmalarına bakabilirsiniz. +* [Bubble sort](https://tsafaelmali.medium.com/bubble-sort-algoritmas%C4%B1-nedir-9811bd921b8d) linkinden basit bir sorting algoritması olan "bubble sort" algoritmasına bakabilirsiniz. + diff --git a/veri-yapilari-algoritmalar/stack/readme.md b/veri-yapilari-algoritmalar/stack/readme.md index 16e385321..67dfc5e41 100644 --- a/veri-yapilari-algoritmalar/stack/readme.md +++ b/veri-yapilari-algoritmalar/stack/readme.md @@ -1 +1,39 @@ -# +# Konu Metni + +## Stack + +Stack (**yığın**), tek taraftan ekleme ve çıkarma yapılabilen bir veri yapısıdır. + +Örneğin, tabakların üst üste dizildiğini düşünelim. Bu yapıda tabaklar sadece en üstten alındığından ve en üste yeni bir tabak koyulabildiğinden dolayı bu yapı bir stack'tir. Stack'te yeni bir eleman eklemeye **push**, bir eleman çıkarmaya **pop** adı verilir. Son giren tabak, her zaman ilk çıkacağı için stack, son giren ilk çıkar anlamına gelen "**Last in first out**", kısaca **LIFO** bir yapıdır. + +Bu veri yapısının kullanışlı olduğu yerlerden biri, işlemlerin önceliklerinin farklı olduğu bir işlem listesidir. Önceliği yüksek olan işlemler en üst sıralarda yer alır ve en önce bitirilir. Çok önemli olmayan işlemler ise en alt sıralarda kalır ve en son bitirilir. + + + +# Sorular + +1. Gerçek hayattan bir stack veri yapısı örneği veriniz. + +2. [Hackerrank problemi](https://www.hackerrank.com/challenges/maximum-element/problem) linkine giderek stack problemini çözünüz. + +3. Bir Python liste veri yapısını stack olarak kullanmak istersek push ve pop işlemlerini nasıl yapabiliriz, kod yazarak gösteriniz. + + Cevap: + + ````python + # stack adında bir liste oluşturalım + stack = [1, 3, 5] + + # push işlemi için "append" metodunu kullanabiliriz + stack.append(7) # stack = [1, 3, 5, 7] + + # pop işlemi için yine "pop" metodunu kullanabiliriz + stack.pop() # stack = [1, 3, 5] + ```` + + + +# Ücretsiz Kaynak + +* [Medium paylaşımı](https://medium.com/@tolgahan.cepel/do%C4%9Frusal-veri-yap%C4%B1lar%C4%B1-3-y%C4%B1%C4%9F%C4%B1t-stack-6c5db18ee934) linkinde ayrıntılı ve resimli bir stack anlatımı bulabilirsiniz. + diff --git a/veri-yapilari-algoritmalar/time-complexity/readme.md b/veri-yapilari-algoritmalar/time-complexity/readme.md index 16e385321..e1442d44e 100644 --- a/veri-yapilari-algoritmalar/time-complexity/readme.md +++ b/veri-yapilari-algoritmalar/time-complexity/readme.md @@ -1 +1,34 @@ -# +# Konu Metni + +## Time Complexity + +Time complexity (zaman karmaşıklığı), bir algoritmanın girdi sayısına bağlı olarak kaç tane işlem yapması gerektiğinin ifadesidir. + +Time complexity, farklı girdiler için farklı olabilir. Örneğin, isimlerden oluşan bir array'de belirli isimleri array'in başından sonuna kadar dolaşarak aradığımızı düşünelim. Ahmet ismi array'in başında, Mehmet ismi ortasında ve Ali ismi ise sonunda olsun. Ahmet ismini ararken çok hızlı bir şekilde buluruz ancak Ali ismini ararken array'in sonuna kadar gitmemiz gerekmektedir. Bu farklı durumlara "case" adı verilir ve genel olarak 3 case vardır: + +1. **Best case**: En iyi durumdur. Yukarıdaki örnekte Ahmet ismini arama durumudur ve bu örnekte 1 birim zaman alır. Algoritmanın genel performansını yansıtmaz. +2. **Average case**: Ortalama durumdur. Yukarıdaki örnekte Mehmet ismini arama durumudur ve bu örnekte array'in yarısı dolaşıldığından dolayı array uzunluğunun yarısı kadar zaman alır. Ortalama performansı yansıtsa da en çok kullanılan case değildir. +3. **Worst case**: En kötü durumdur. Yukarıdaki örnekte Ali ismini arama durumudur ve bu örnekte tüm array dolaşıldığından dolayı array'in uzunluğu kadar zaman alır. En kötü performansı yansıtsa da algoritma için bir alt performans sınırı belirler. Bu yüzden en çok kullanılan case'dir. + + + +# Sorular + +1. Best case'i worst case'i ile aynı zamanı alan bir işlem söyleyin. + + Cevap: Bir array'de belli bir indeksteki elemana ulaşmak. + +2. Neden average case değil de worst case daha çok kullanılan bir case'tir? + + Cevap: Genelde worst case hesaplaması average case'e göre daha kolaydır ve average case girdilerin dağılımına göre değişiklik gösterebilir. Ayrıca, worst case algoritmanın en alt performans sınırını belirler. + +3. "n" adet elemanı olan ve hash collision'ları önlemek için separate chaining kullanılan bir hash table'ın bir elemanının aranması durumunda worst case kaç birim zaman alır? + + Cevap: Worst case, tüm verilerin bir hash table indeksinde çakıştığı durumdur. Eğer aranan eleman o indeksteki linked list'in sonunda ise arama işlemi "n" birim zaman alır. + + + +# Ücretsiz Kaynak + +* [Time complexity](https://tr.ilusionity.com/216-what-is-big-o-notation-explained-space-and-time-complexity) linkine giderek time complexity ve algoritma analizi hakkında bilgi edinebilirsiniz. + diff --git a/veri-yapilari-algoritmalar/veri-tutulma/readme.md b/veri-yapilari-algoritmalar/veri-tutulma/readme.md index 16e385321..e3fbba7a9 100644 --- a/veri-yapilari-algoritmalar/veri-tutulma/readme.md +++ b/veri-yapilari-algoritmalar/veri-tutulma/readme.md @@ -1 +1,40 @@ -# +# Konu Metni + +## Bilgisayarda Verinin Tutulması + +Bilgisayarlar, her türlü veriyi 0 ve 1 sembollerini kullanarak saklar. 0 veya 1 sembolünü tutan bir yapıya "**bit**" adı verilir. Bir "bit", 0 veya 1 rakamını saklayabildiğinden dolayı 2 farklı değeri ifade edebilir. Bu "bit" adı verilen yapılar art arda sıralanarak daha büyük bilgileri ifade edebilir. Örneğin; "1000001" sayısının bilgisayarda "A" harfini ifade edebildiğini görmüştük. Bu sayıdaki her rakam birer "bit"tir ve bu sayı toplamda 7 adet "bit"ten oluşmaktadır. + +ASCII karakterleri gördüğümüz gibi 7 adet bit kullanılarak oluşturulmuştur. Her bir bit 2 farklı değeri ifade edebildiğinden dolayı 7 bit de "2 üzeri 7" yani "128" farklı değer ifade edebilir. O zaman ASCII karakter setinin 128 karakterden oluştuğunu söyleyebiliriz. + +8 adet bit, bir "**bayt**" anlamına gelir. Bilgisayarda herhangi bir dosyanın ne kadar yer kapladığına baktığımızda hep sonu "bayt" ile biten ifadeler (Kilobayt, megabayt gibi) görürüz. Bu ifadelerin ne olduklarını şöyle ifade edebiliriz: + +* 1 kilobayt = 1024 bayt +* 1 megabayt = 1024 kilobayt +* 1 gigabayt = 1024 megabayt + +### Verinin bilgisayarda fiziksel olarak saklanması + +Peki bu 0 ve 1 bilgileri bilgisayarın içinde nasıl saklanıyor? + +Veriler kalıcı veya geçici olarak bilgisayarda saklanabilir. Kalıcı olarak saklanan bilgiler, sabit disklerde saklanır. Bir Hard Disk depolama biriminde veriler manyetik alan kullanılarak diskin üzerine yazılır. İki farklı manyetik kutup, ikili sistemdeki 0 ve 1 sembollerini temsil eder. Geçici olarak saklanan bilgiler ise RAM adı verilen hafıza biriminde, elektrik kullanılarak saklanır. Bilgisayar kapandığında ise elektrik kesildiğinden dolayı RAM biriminin içindeki bilgiler kaybolur. + + + +# Sorular + +1. Bir adet bayt kaç farklı değer ifade edebilir? + + Cevap: Bir bayt 8 adet bitten oluşur ve "2 üzeri 8" yani 256 farklı değer ifade edebilir. + +2. 1 gigabayt kaç kilobayttır? + + Cevap: 1024x1024 = 2^20 = 1.048.576 + +3. Hard Disk dışında depolama birimleri var mıdır? Araştırınız. + + + +# Ücretsiz Kaynak + +* [Verilerin disklerde depolanması](https://www.goldverikurtarma.com/veriler-disklerde-nasil-depolaniyor) linkinden verilerin sabit disklerde nasıl depolandığını daha detaylı bir şekilde öğrenebilirsiniz. +