-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #86 from inzva/muratbiberoglu-patch
updated filenames & separated content of ds page
- Loading branch information
Showing
34 changed files
with
836 additions
and
736 deletions.
There are no files selected for viewing
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. | ||
} | ||
``` |
Oops, something went wrong.