Skip to content

Commit

Permalink
Merge pull request #86 from inzva/muratbiberoglu-patch
Browse files Browse the repository at this point in the history
updated filenames & separated content of ds page
  • Loading branch information
muratbiberoglu authored Oct 11, 2024
2 parents 4f7a75d + 547c07c commit 658bca1
Show file tree
Hide file tree
Showing 34 changed files with 836 additions and 736 deletions.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
14 changes: 12 additions & 2 deletions docs/algorithms-i/index.md → docs/algorithms/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
---
title: Algorithms - I
title: Algorithms
tags:
- "Algorithms"
- Algorithms
- Linear Search
- Binary Search
- Ternary Search
- Sorting Algorithms
- Insertion Sort
- Merge Sort
- Quick Sort
- Radix Sort
- Quickselect Algorithm
- Divide and Conquer
---

**Editor:** Kadir Emre Oto
Expand Down
698 changes: 0 additions & 698 deletions docs/data-structures-i/index.md

This file was deleted.

31 changes: 31 additions & 0 deletions docs/data-structures/deque.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
title: Deque
tags:
- Data Structures
- Deque
---

Deque veri yapısı stack ve queue veri yapılarına göre daha kapsamlıdır. Bu veri yapısında yapının en üstüne eleman eklenebilirken aynı zamanda en altına da eklenebilir. Aynı şekilde yapının hem en üstündeki elemanına hem de en alttaki elemanına erişim ve silme işlemleri uygulanabilir. Bu veri yapısında uyguluyabildiğimiz işlemler:

- Veri yapısının en üstüne eleman ekleme.
- Veri yapısının en altına eleman ekleme.
- Veri yapısının en üstündeki elemanına erişim.
- Veri yapısının en altındaki elemanına erişim.
- Veri yapısının en üstündeki elemanı silme.
- Veri yapısının en altındaki elemanı silme.

C++ dilindeki STL kütüphanesinde bulunan hazır deque yapısının kullanımı aşağıdaki gibidir:

```c++
int main() {
deque<int> q;
q.push_front(5); // deque'nin en altina 5'i ekler.
q.push_back(6); // deque'nin en ustune 6'yi ekler.
int x = q.front(); // deque'nin en altindaki elemanina erisim.
int y = q.back(); // deque'nin en ustundeki elemanina erisim.
q.pop_front(); // deque'nin en altindaki elemanini silme.
q.pop_back(); // deque'nin en ustundeki elemanini silme.
}
```

**P.S.** deque veri yapısı stack ve queue veri yapılarına göre daha kapsamlı olduğundan ötürü stack ve queue veri yapılarına göre 2 kat fazla memory kullandığını açıklıkla söyleyebiliriz.
120 changes: 120 additions & 0 deletions docs/data-structures/fenwick-tree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
title: Fenwick Tree
tags:
- Data Structures
- Fenwick Tree
- Binary Indexed Tree
- BIT
---

Binary Indexed Tree olarak da bilinen Fenwick Tree, [Prefix Sum](prefix-sum.md) ve [Sparse Table](sparse-table.md) yapılarına benzer bir yapıda olup dizi üzerinde değişiklik yapabilmemize olanak sağlayan bir veri yapısıdır. Fenwick Tree'nin diğer veri yapılarına göre en büyük avantajı pratikte daha hızlı olması ve hafıza karmaşıklığının $\mathcal{O}(N)$ olmasıdır. Ancak Fenwick Tree'de sadece prefix cevapları (veya suffix cevapları) saklayabildiğimizden aralıklarda minimum, maksimum ve EBOB gibi bazı sorguların cevaplarını elde edemeyiz.

## Yapısı ve Kuruluşu

$g(x)$, $x$ sayısının bit gösteriminde yalnızca en sağdaki bitin 1 olduğu tam sayı olsun. Örneğin $20$'nin bit gösterimi $(10100)_2$ olduğundan $g(20)=4$'tür. Çünkü ilk kez sağdan $3.$ bit $1$'dir ve $(00100)_2=4$'tür. Fenwick Tree'nin $x$ indeksli düğümünde, <span style="white-space: nowrap">$x - g(x) + 1$</span> indeksli elemandan $x$ indeksli elemana kadar olan aralığın cevabını saklayacak şekilde kurulur.

<figure markdown="span">
![8 uzunluğundaki bir dizi için kurulmuş Fenwick Tree yapısı](img/fenwick.png){ width="80%" }
<figcaption>$8$ uzunluğundaki bir dizi için kurulmuş Fenwick Tree yapısı</figcaption>
</figure>


## Sorgu Algoritması

Herhangi bir $[1,x]$ aralığı için sorgu algoritması sırası ile şu şeklide çalışır:

1. Aradığımız cevaba $[x - g(x) + 1,x]$ aralığının cevabını ekle.
2. $x$'in değerini $x - g(x)$ yap. Eğer $x$'in yeni değeri $0$'dan büyük ise $1.$ işlemden hesaplamaya devam et.

$[1,x]$ aralığının cevabını hesaplamak için yapılan işlem sayısı $x$ sayısının $2$'lik tabandaki yazılışındaki $1$ sayısına eşittir. Çünkü her döngüde $x$'ten $2$'lik tabandaki yazılışındaki en sağdaki $1$ bitini çıkartıyoruz. Dolayısıyla sorgu işlemimiz $\mathcal{O}(\log N)$ zaman karmaşıklığında çalışır. $[l,r]$ aralığının cevabını da $[1,r]$ aralığının cevabından $[1,l - 1]$ aralığının cevabını çıkararak kolay bir şekilde elde edebiliriz.

> NOT: $g(x)$ değerini bitwise operatörlerini kullanarak aşağıdaki eşitlikle kolay bir şekilde hesaplayabiliriz:
> \\[g(x) = x \ \& \ (-x)\\]
## Eleman Güncelleme Algoritması

Dizideki $x$ indeksli elemanının değerini güncellemek için kullanılan algoritma şu şeklide çalışır:

- Ağaçta $x$ indeksli elemanı içeren tüm düğümlerin değerlerini güncelle.

Fenwick Tree'de $x$ indeksli elemanı içeren maksimum $\log(N)$ tane aralık olduğundan güncelleme algoritması $\mathcal{O}(\log N)$ zaman karmaşıklığında çalışır.

## Örnek Kod Parçaları

```c++
const int n;
int tree[n + 1], a[n + 1];

void add(int val, int x) { // x indeksli elemanin degerini val degeri kadar artirir.
// x indeksinin etkiledigi butun dugumleri val degeri kadar artirir.
while (x <= n) {
tree[x] += val;
x += x & (-x);
}
}

int sum(int x) { // 1 indeksli elemandan x indeksli elemana
int res = 0; // kadar olan sayilarin toplamini verir.
while (x >= 1) {
res += tree[x];
x -= x & (-x);
}
return res;
}

int query(int l, int r) { // [l,r] araligindaki elemanlarin toplamini verir.
return sum(r) - sum(l - 1);
}

void build() { // a dizisi uzerine fenwick tree yapisini kuruyoruz.
for (int i = 1; i <= n; i++)
add(a[i], i);
}
```
Fenwick Tree veri yapısı ile ilgili örnek bir probleme [buradan](https://www.spoj.com/problems/CSUMQ) ulaşabilirsiniz.
## Aralık Güncelleme ve Eleman Sorgu
Bir $a$ dizisi üzerinde işlemler yapacağımızı varsayalım daha sonra $a$ dizisi $b$ dizisinin prefix sum dizisi olacak şekilde bir $b$ dizisi tanımlayalım. Başka bir deyişle $a_i = \displaystyle\sum_{j=1}^{i} {b_j} $ olmalıdır. Sonradan oluşturduğumuz $b$ dizisi üzerine Fenwick Tree yapısını kuralım. $[l,r]$ aralığındaki her elemana
$x$ değerini eklememiz için uygulamamız gereken işlemler:
- $b_l$ değerini $x$ kadar artır. Böylelikle $l$ indeksli elemandan dizinin sonuna kadar tüm elemanların değeri $x$ kadar artmış olur.
- $b_{r + 1}$ değerini $x$ kadar azalt. Böylelikle $r + 1$ indeksli elemandan dizinin sonuna kadar tüm elemanların değeri $x$ kadar azalmış olur. Bu işlemelerin sonucunda sadece $[l,r]$ aralığındaki elemanların değeri $x$ kadar artmış olur.
### Örnek Kod Parçaları
```c++
const int n;
int a[n + 1], b[n + 1];
void add(int val, int x) { // x indeksli elemanin degerini val degeri kadar artirir.
while (x <= n) {
tree[x] += val;
x += x & (-x);
}
}
int sum(int x) { // 1 indeksli elemandan x indeksli elemana
int res = 0; // kadar olan sayilarin toplamini verir.
while (x >= 1) {
res += tree[x];
x -= x & (-x);
}
return res;
}
void build() {
for (int i = 1; i <= n; i++)
b[i] = a[i] - a[i - 1]; // b dizisini olusturuyoruz.
for (int i = 1; i <= n; i++)
add(b[i], i); // b dizisi uzerine fenwick tree kuruyoruz.
}
void update(int l, int r, int x) {
add(x, l);
add(-x, r + 1);
}
void query(int x) { return sum(x); }
```
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
60 changes: 60 additions & 0 deletions docs/data-structures/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
title: Data Structures
tags:
- Data Structures
---

**Editor:** Tahsin Enes Kuru

**Reviewers:** Baha Eren Yaldız, Burak Buğrul

**Contributors:** Kerim Kochekov

## Giriş

Bilgisayar biliminde veri yapıları, belirli bir eleman kümesi üzerinde verimli bir şeklide bilgi edinmemize aynı zamanda bu elemanlar üzerinde değişiklikler yapabilmemize olanak sağlayan yapılardır. Çalışma prensipleri genellikle elemanların değerlerini belirli bir kurala göre saklamak daha sonra bu yapıları kullanarak elemanlar hakkında sorulara (mesela, bir dizinin belirli bir aralığındaki en küçük sayıyı bulmak gibi) cevap aramaktır.

## Dinamik Veri Yapıları

### [Linked List](linked-list.md)
### [Stack](stack.md)
### [Queue](queue.md)
### [Deque](deque.md)
### [Fenwick Tree](fenwick-tree.md)
### [Segment Tree](segment-tree.md)

## Statik Veri Yapıları

### [Prefix Sum](prefix-sum.md)
### [Sparse Table](sparse-table.md)
### [SQRT Decomposition](sqrt-decomposition.md)

## Örnek Problemler

Veri yapıları üzerinde pratik yapabilmeniz için önerilen problemler:

1. [Link](https://codeforces.com/problemset/problem/797/C){target="_blank"}
2. [Link](https://codeforces.com/contest/276/problem/C){target="_blank"}
3. [Link](https://codeforces.com/contest/380/problem/C){target="_blank"}
4. [Link](https://www.hackerearth.com/problem/algorithm/benny-and-sum-2){target="_blank"}
5. [Link](https://www.hackerearth.com/practice/data-structures/advanced-data-structures/fenwick-binary-indexed-trees/practice-problems/algorithm/counting-in-byteland){target="_blank"}

## Faydalı Bağlantılar

1. <https://en.wikipedia.org/wiki/Data\_structure>{target="_blank"}
2. <https://cp-algorithms.com/data\_structures/sparse-table.html>{target="_blank"}
3. <https://cp-algorithms.com/data\_structures/segment\_tree.html>{target="_blank"}
4. <https://cp-algorithms.com/data\_structures/fenwick.html>{target="_blank"}
5. <https://cp-algorithms.com/data\_structures/sqrt\_decomposition.html>{target="_blank"}
6. <https://cses.fi/book/book.pdf>{target="_blank"}
7. <https://visualgo.net/en/segmenttree>{target="_blank"}
8. <https://visualgo.net/en/fenwicktree>{target="_blank"}
9. <https://www.geeksforgeeks.org/binary-indexed-tree-or-fenwick-tree-2>{target="_blank"}
10. <http://www.cs.ukzn.ac.za/~hughm/ds/slides/20-stacks-queues-deques.pdf>{target="_blank"}
11. <https://www.geeksforgeeks.org/stack-data-structure>{target="_blank"}
12. <https://www.geeksforgeeks.org/queue-data-structure>{target="_blank"}
13. <https://www.geeksforgeeks.org/deque-set-1-introduction-applications>{target="_blank"}
14. <https://www.geeksforgeeks.org/linked-list-set-1-introduction>{target="_blank"}
15. <https://www.geeksforgeeks.org/binary-indexed-tree-range-updates-point-queries>{target="_blank"}
16. <https://visualgo.net/en/list>{target="_blank"}
17. <https://cp-algorithms.com/data\_structures/fenwick.html>{target="_blank"}
53 changes: 53 additions & 0 deletions docs/data-structures/linked-list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: Linked List
tags:
- Data Structures
- Linked List
---

Linked List veri yapısında elemanlar, her eleman kendi değerini ve bir sonraki elemanın adresini tutacak şekilde saklanır. Yapıdaki elemanlar baş elemandan (head) başlanarak son elemana (tail) gidecek şekilde gezilebilir. Diziye karşın avantajı hafızanın dinamik bir şekilde kullanılmasıdır. Bu veri yapısında uygulanabilecek işlemler:

- Veri yapısının sonuna eleman ekleme.
- Anlık veri yapısını baştan (head) sona (tail) gezme.

<figure markdown="span">
![Örnek bir Linked List yapısı](img/linkedlist.png){ width="100%" }
<figcaption>Örnek bir Linked List yapısı</figcaption>
</figure>

```c++
// Her bir elemani (burada sayilari, yani int) tutacak struct olusturuyoruz.
struct node {
int data;
node *next;
};
node *head, *tail;

void push_back(int x) {
// Yeni elemanimizi hafizada olusturuyoruz.
node *t = (node *)malloc(sizeof(node));
t->data = x; // Elemanin verisini atiyoruz.
t->next = NULL; // Sona ekledigimizden sonraki elemanina NULL atiyoruz.

// Eger veri yapimiza hic eleman eklenmediyse head
// ve tail elemanlarini olusturuyoruz.
if (head == NULL && tail == NULL) {
head = t;
tail = t;
}
// Eklenmisse yeni tail elemanimizi guncelliyoruz.
else {
tail->next = t;
tail = t;
}
}

void print() {
// Dizideki tum elemanlari geziyoruz.
node *t = head;
while (t != NULL) {
printf("%d ", t->data);
t = t->next;
}
}
```
53 changes: 53 additions & 0 deletions docs/data-structures/prefix-sum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: Prefix Sum
tags:
- Data Structures
- Prefix Sum
---

Prefix Sum dizisi bir dizinin prefixlerinin toplamlarıyla oluşturulan bir veri yapısıdır. Prefix sum dizisinin $i$ indeksli elemanı girdi dizisindeki $1$ indeksli elemandan $i$ indeksli elemana kadar olan elemanların toplamına eşit olacak şekilde kurulur. Başka bir deyişle:

$$sum_i = \sum_{j=1}^{i} {a_j}$$

Örnek bir $A$ dizisi için prefix sum dizisi şu şekilde kurulmalıdır:

<div align="center" markdown="1">
| **A Dizisi** | $4$ | $6$ | $3$ | $12$ | $1$ |
|-------------------:|:---:|:-----:|:-------:|:----------:|:------------:|
| **Prefix Sum Dizisi** | $4$ | $10$ | $13$ | $25$ | $26$ |
| | $4$ | $4+6$ | $4+6+3$ | $4+6+3+12$ | $4+6+3+12+1$ |
</div>

Prefix sum dizisini kullanarak herhangi bir $[l,r]$ aralığındaki elemanların toplamını şu şekilde kolaylıkla elde edebiliriz:

$$sum_r = \sum_{j=1}^{r} {a_j}$$

$$sum_{l - 1} = \sum_{j=1}^{l - 1} {a_j}$$

$$sum_r - sum_{l-1} = \sum_{j=l}^{r} {a_j}$$

## Örnek Kod Parçaları

Prefix Sum dizisini kurarken $sum_i = sum_{i - 1} + a_i$ eşitliği kolayca görülebilir ve bu eşitliği kullanarak $sum[]$ dizisini girdi dizisindeki elemanları sırayla gezerek kurabiliriz:

```c++
const int n;
int sum[n + 1], a[n + 1];
// a dizisi girdi dizimiz, sum dizisi de prefix sum dizimiz olsun.

void build() {
for (int i = 1; i <= n; i++)
sum[i] = sum[i - 1] + a[i];
return;
}

int query(int l, int r) {
return sum[r] - sum[l - 1];
}
```
## Zaman Karmaşıklığı
Prefix sum dizisini kurma işlemimizin zaman ve hafıza karmaşıklığı $\mathcal{O}(N)$. Her sorguya da $\mathcal{O}(1)$ karmaşıklıkta cevap verebiliyoruz.
Prefix sum veri yapısı ile ilgili örnek bir probleme [buradan](https://codeforces.com/problemset/problem/816/B){target="_blank"} ulaşabilirsiniz.
28 changes: 28 additions & 0 deletions docs/data-structures/queue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
title: Queue
tags:
- Data Structures
- Queue
---

Queue veri yapısında elemanlar yapıya ilk giren ilk çıkar (FIFO) kuralına uygun olacak şekilde saklanır. Bu veri yapısında uygulayabildigimiz işlemler:

- Veri yapısının en üstüne eleman ekleme.
- Veri yapısının en altındaki elemanına erişim.
- Veri yapısının en altındaki elemanı silme.
- Veri yapısının boş olup olmadığının kontrölü.

C++ dilindeki STL kütüphanesinde bulunan hazır queue yapısının kullanımı aşağıdaki gibidir:

```c++
int main() {
queue<int> q;
cout << q.empty() << endl; // Ilk bashta Queue bosh oldugu icin burada True donecektir.
q.push(5); // Queue'in en ustune 5'i ekler. Queue'in yeni hali: {5}
q.push(7); // Queue'in en ustune 7'yi ekler. Queue'in yeni hali: {7, 5}
q.push(6); // Queue'in en ustune 6'yi ekler. Queue'in yeni hali : {6, 7, 5}
q.pop(); // Queue'in en altindaki elemani siler. Queue'in yeni hali : {6, 7}
q.push(1); // Queue'in en ustune 1'i ekler. Queue'in yeni hali : {1, 6, 7}
cout << Q.front() << endl; // Queue'in en ustundeki elemana erisir. Ekrana 7 yazdirir.
}
```
Loading

0 comments on commit 658bca1

Please sign in to comment.