Repositori ini berisi contoh-contoh algoritme dan struktur data yang populer menggunakan JavaScript.
Setiap algoritme dan struktur data memiliki README-nya tersendiri dengan penjelasan yang berkaitan dan tautan untuk bacaan lebih lanjut (termasuk tautan menuju video YouTube).
_☝ Perhatikan bahwa proyek ini hanya dimaksudkan untuk tujuan pembelajaran dan riset, dan **tidak** dimaksudkan untuk digunakan sebagai produksi._
## Struktur Data
Struktur data adalah cara tertentu untuk mengatur dan menyimpan data dalam komputer sehingga dapat diakses dan diubah secara efisien. Lebih tepatnya, struktur data adalah kumpulan dari nilai data, relasi di antara data-data, dan fungsi atau operasi yang dapat diterapkan pada data.
Algoritme adalah sebuah perincian yang jelas tentang cara untuk memecahkan suatu masalah. Ia adalah sekumpulan aturan yang menjelaskan secara tepat urutan-urutan dari sebuah operasi.
`P` - Pemula, `L` - Lanjutan
### Algoritme Berdasarkanan Topik
- **Matematika**
-`P` [Manipulasi Bit](src/algorithms/math/bits) - menetapkan/mendapatkan/memperbarui/mengahpus bit, perkalian/pembagian dengan angka 2, membuat bilangan negatif etc.
-`P` [Faktorial](src/algorithms/math/Faktorial)
-`P` [Bilangan Fibonacci](src/algorithms/math/fibonacci) - versi klasik dan bentuk tertutup
-`P` [Faktor Prima](src/algorithms/math/prime-factors) - menemukan faktor prima dan menghitungnya menggunakan teorema Hardy-Ramanujan
-`P` [Pengujian Bilangan Prima](src/algorithms/math/primality-test) (metode _trial division_)
-`P` [Algoritme Euclidean](src/algorithms/math/euclidean-algorithm) - menghitung Faktor Persekutuan Terbesar (FPB)
-`P` [_Least Common Multiple_](src/algorithms/math/least-common-multiple) (LCM)
-`P` [_Sieve of Eratosthenes_](src/algorithms/math/sieve-of-eratosthenes) - menemukan semua bilangan prima hingga batas yang ditentukan
-`P` [_Is Power of Two_](src/algorithms/math/is-power-of-two) - mengecek apakah sebuah bilangan adalah hasil dari pangkat dua (algoritme _naive_ dan _bitwise_)
-`L` [Jembatan](src/algorithms/graph/bridges) - Algoritme berdasarkan DFS
-`L` [Jalur dan Sirkuit Eulerian](src/algorithms/graph/eulerian-path) - Algoritme Fleury - Mengunjungi setiap tepinya tepat satu kali
-`L` [Siklus Hamiltonian](src/algorithms/graph/hamiltonian-cycle) - mengunjungi setiap sudutnya tepat satu kali
-`L` [Komponen yang Terkoneksi dengan Kuat](src/algorithms/graph/strongly-connected-components) - Algoritme Kosaraju
-`L` [Permasalahan Penjual Keliling](src/algorithms/graph/travelling-salesman) - kemungkinan rute terpendek untuk mengunjungi setiap kota dan kembali lagi ke kota asal
- **Kriptografi**
-`P` [Polinomial Hash](src/algorithms/cryptography/polynomial-hash) - fungsi rolling hash berdasarkan polinomial
-`P` [NanoNeuron](https://github.com/trekhleb/nano-neuron) - 7 fungsi JS sederhana yang mengilustrasikan bagaimana mesin-mesin dapat benar-benar belajar (perambatan maju/mundur)
-`P` [Permainan Melompat](src/algorithms/uncategorized/jump-game) - runut-balik, pemrograman dinamis (atas ke bawah + bawah ke atas) and contoh-contoh _greedy_
Paradigma algoritmik adalah sebuah metode atau pendekatan umum yang mendasari desain sebuah tingkatan algoritme. Paradigma algoritmik merupakan abstraksi yang lebih tinggi dari gagasan sebuah algoritme, seperti halnya sebuah algoritme merupakan abstraksi yang lebih tinggi dari sebuah program komputer.
- **_Brute Force_** - melihat ke semua kemungkinan dan memilih solusi yang terbaik
-`L` [Permasalahan Penjual Keliling](src/algorithms/graph/travelling-salesman) - kemungkinan rute terpendek untuk mengunjungi setiap kota dan kembali lagi ke kota asal
-`L` [Transformasi Diskrit Fourier](src/algorithms/math/fourier-transform) - menguraikan fungsi waktu (sinyal) menjadi frekuensi yang menyusunnya
- **_Greedy_** - memilih pilihan terbaik pada saat ini tanpa mempertimbangkan masa yang akan datang
- **Runut-balik** - sama halnya dengan _brute force_, algoritme ini mencoba untuk menghasilkan segala kemungkinan solusi, tetapi setiap kali anda menghasilkan solusi selanjutnya, anda akan menguji apakah solusi tersebut memenuhi semua kondisi dan setelah itu baru akan menghasilkan solusi berikutnya. Apabila tidak, maka akan merunut-balik dan mencari solusi di jalur yang berbeda. Biasanya menggunakan lintas DFS dari ruang keadaan.
-`L` [_Combination Sum_](src/algorithms/sets/combination-sum) - menemukan semua kombinasi yang membentuk jumlah tertentu
- **_Mencabang dan Membatasi_** - digunakan untuk membuang solusi parsial dengan biaya yang lebih besar dari solusi dengan biaya yang terendah yang ditemukan sejauh ini dengan cara mengingat solusi dengan biaya terendah yang ditemukan pada setiap tahap dari pencarian runut-balik dan menggunakan biaya dari solusi dengan biaya terendah sejauh ini sebagai batas bawah pada biaya dari solusi dengan biaya yang paling sedikit untuk permasalahannya. Biasanya menggunakan lintas BFS yang berkombinasi dengan lintas DFS dari pohon ruang keadaan.
## Cara menggunakan repositori ini
**Meng-_install_ semua dependensi**
```
npm install
```
**Menjalankan ESLint**
Anda dapat menjalankannya untuk memeriksa kualitas kode.
```
npm run lint
```
**Menjalankan semua tes**
```
npm test
```
**Menjalankan tes berdasarkan nama**
```
npm test -- 'LinkedList'
```
**_Playground_**
Anda dapat bermain dengan algoritme dan struktur data di _file_`./src/playground/playground.js` dan menuliskan tesnya di `./src/playground/__test__/playground.test.js`.
Lalu, hanya tinggal menjalankan perintah berikut untuk mengetes apakah kode _playground_ anda bekerja sesuai dengan keinginan:
```
npm test -- 'playground'
```
## Informasi Bermanfaat
### Referensi
[▶ Algoritme dan Struktur Data di YouTube](https://www.youtube.com/playlist?list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8)
### Notasi _Big O_
Notasi _Big O_ digunakan untuk mengklasifikasikan algoritme berdasarkan durasi atau ruang yang dibutuhkan seiring bertambahnya _input_. Pada grafik dibawah, anda dapat menemukan urutan pertumbuhan yang paling umum dari algoritme yang ditentukan dalam notasi _Big O_.
![Big O graphs](./assets/big-o-graph.png)
Sumber: [Big O Cheat Sheet](http://bigocheatsheet.com/).
Di bawah ini adalah daftar dari beberapa notasi _Bog O_ yang sering digunakan dan perbandingan kinerjanya terhadap berbagai ukuran _input data_.
| Notasi _Big O_ | Komputasi untuk 10 elemen | Komputasi untuk 100 elemen | Komputasi untuk 1000 elemen |
| **Merge Sort (Sortir Gabungan)** | n log(n) | n log(n) | n log(n) | n | Ya | |
| **Quick sort (Sortir Cepat)** | n log(n) | n log(n) | n<sup>2</sup> | log(n) | Tidak | Sortir Cepat biasanya dilakukan secara _in-place_ dengan O(log(n)) ruang tumpukan |
| **Shell sort (Sortir Shell)** | n log(n) | tergantung pada jarak urutan | n (log(n))<sup>2</sup> | 1 | Tidak | |
| **Counting sort (Sortir Perhitungan)** | n + r | n + r | n + r | n + r | Ya | r - angka terbesar dalam larik |
| **Radix sort (Sortir Akar)** | n \* k | n \* k | n \* k | n + k | Ya | k - panjang dari kunci terpanjang |
## Pendukung Proyek
> Anda dapat mendukung proyek ini via ❤️️ [GitHub](https://github.com/sponsors/trekhleb) atau ❤️️ [Patreon](https://www.patreon.com/trekhleb).
[Orang-orang yang mendukung proyek ini](https://github.com/trekhleb/javascript-algorithms/blob/master/BACKERS.md) `∑ = 1`
> ℹ️ A few more [projects](https://trekhleb.dev/projects/) and [articles](https://trekhleb.dev/blog/) about JavaScript and algorithms on [trekhleb.dev](https://trekhleb.dev)