*☝ Si noti che questo progetto è destinato ad essere utilizzato solo per l'apprendimento e la ricerca e non è destinato ad essere utilizzato per il commercio.*
Даний репозиторій приклади багатьох популярних алгоритмів та структур даних на основі JavaScript.
Кожен алгоритм та структура даних має свій окремий README-файл із відповідними поясненнями та посиланнями для подальшого вивчення (включаючи посилання на відео на YouTube).
_Вивчення матеріалу на інших мовах:_
[_English_](README.md),
[_简体中文_](README.zh-CN.md),
[_繁體中文_](README.zh-TW.md),
[_한국어_](README.ko-KR.md),
[_日本語_](README.ja-JP.md),
[_Polski_](README.pl-PL.md),
[_Français_](README.fr-FR.md),
[_Español_](README.es-ES.md),
[_Português_](README.pt-BR.md),
[_Русский_](README.ru-RU.md),
[_Türk_](README.tr-TR.md),
[_Italiana_](README.it-IT.md)
*☝ Зверніть увагу! Даний проект призначений лише для навчальних та дослідницьких цілей, і він **не** призначений для виробництва (продакшн).*
## Структури даних
Структура даних (в програмуванні) - це спосіб організації даних в комп'ютерах. Часто разом зі структурою даних пов'язується і специфічний перелік операцій, що можуть бути виконаними над даними, організованими в таку структуру.
Точніше, структура даних - це сукупність даних цінності, взаємозв'язки між ними та функції або операції, до яких можна застосувати дані.
* `B` [Пошук блоків](src/algorithms/search/jump-search) - пошук у відсортованому масиві
* `B` [Двійковий пошук](src/algorithms/search/binary-search) - знаходження заданого значення у впорядкованому масиві
* `B` [Інтерполяційний алгоритм пошуку](src/algorithms/search/interpolation-search) - алгоритм для пошуку за заданим ключем в індексованому масиві, який впорядкований за значенням ключів
* `B` [Пошук у глибину](src/algorithms/tree/depth-first-search)
* `B` [Пошук у ширину](src/algorithms/tree/breadth-first-search)
* **Графи**
* `B` [Пошук у глибину](src/algorithms/graph/depth-first-search)
* `B` [Пошук у ширину](src/algorithms/graph/breadth-first-search)
* `B` [Алгоритм Крускала](src/algorithms/graph/kruskal) - алгоритм побудови мінімального кістякового дерева зваженого неорієнтовного графа
* `A` [Алгоритм Дейкстри](src/algorithms/graph/dijkstra) - знаходження найкоротшого шляху від однієї вершини графа до всіх інших вершин
* `A` [Алгоритм Беллмана — Форда](src/algorithms/graph/bellman-ford) - алгоритм пошуку найкоротшого шляху в зваженому графі
* `A` [Алгоритм Флойда — Воршелла](src/algorithms/graph/floyd-warshall) - знаходження найкоротшого шляху в зваженому графі з додатними або від'ємними вагами ребер (але без від'ємнозначних циклів)
* `A` [Циклічний граф](src/algorithms/graph/detect-cycle) - граф, що складається з єдиного циклу, або, іншими словами, деякого числа вершин, з'єднаних замкнутим ланцюгом.
* `A` [Алгоритм Прима](src/algorithms/graph/prim) - жадібний алгоритм побудови мінімального кістякового дерева зваженого зв'язного неорієнтованого графа
* `A` [Топологічне сортування](src/algorithms/graph/topological-sorting) - впорядковування вершин безконтурного орієнтованого графа згідно з частковим порядком, визначеним ребрами цього графу на множині його вершин
* `A` [Алгоритм Тар'яна](src/algorithms/graph/articulation-points) - алгоритм пошуку компонент сильної зв'язності в орієнтованому графі, що працює за лінійний час
* `A` [Задача комівояжера](src/algorithms/graph/travelling-salesman) - знаходження найвигіднішого маршруту, що проходить через вказані міста хоча б по одному разу
* **Криптографія**
* `B` [Хеш-функція](src/algorithms/cryptography/polynomial-hash) - функція, що перетворює вхідні дані будь-якого (як правило великого) розміру в дані фіксованого розміру.
* `B` [Шифр Цезаря (шифр зсуву)](src/algorithms/cryptography/caesar-cipher) - симетричний моноалфавітний алгоритм шифрування, в якому кожна буква відкритого тексту заміняється на ту, що віддалена від неї в алфавіті на сталу кількість позицій
* `B` [Шифр Гілла](src/algorithms/cryptography/hill-cipher) - поліграмний шифр підстановки, заснований на лінійній алгебрі
* **Машинне навчання**
* `B` [Нано-нейрон](https://github.com/trekhleb/nano-neuron) - 7 простих функцій JS, які ілюструють, як машини насправді можуть навчатися (пряме та зворотнє поширення)
* `B` [Метод k-найближчих сусідів](src/algorithms/ml/knn) - простий непараметричний класифікаційний метод, де для класифікації об'єктів у рамках простору властивостей використовуються відстані (зазвичай евклідові), пораховані до усіх інших об'єктів
* `B` [Кластеризація методом к–середніх](src/algorithms/ml/knn) - популярний метод кластеризації, — впорядкування множини об'єктів в порівняно однорідні групи.
* `B` [Гра стрибків](src/algorithms/uncategorized/jump-game) - зворотне відстеження, динамічне програмування (зверху вниз + знизу вгору) та жадібні приклади
* `B` [Проблема унікальних шляхів](src/algorithms/uncategorized/unique-paths) - зворотне відстеження, динамічне програмування та приклади на основі Трикутника Паскаля
* `B` [Дощові тераси](src/algorithms/uncategorized/rain-terraces) - проблема захоплення дощової води (динамічне програмування та версії грубої сили)
* `B` [Завдання про рекурсивні сходи](src/algorithms/uncategorized/recursive-staircase) - підрахунок кількості способів досягти вершини (4 рішення)
* `A` [Задача про вісім ферзів](src/algorithms/uncategorized/n-queens)
* `A` [Задача про хід коня](src/algorithms/uncategorized/knight-tour)
### Парадигма програмування
Парадиигма програмува́ння — це система ідей і понять, які визначають стиль написання комп'ютерних програм, а також спосіб мислення програміста. Це спосіб концептуалізації, що визначає організацію обчислень і структурування роботи, яку виконує комп'ютер.
* **Метод «грубої сили» або повний перебір** - метод рішення криптографічної задачі шляхом перебору всіх можливих варіантів ключа
* `A` [Задача комівояжера](src/algorithms/graph/travelling-salesman) - знаходження найвигіднішого маршруту, що проходить через вказані міста хоча б по одному разу
* `A` [Дискретне перетворення Фур'є](src/algorithms/math/fourier-transform) - розкладання тимчасової функції (сигналу) на частотні складові
* **"Жадібні" алгоритми** - простий і прямолінійний евристичний алгоритм, який приймає найкраще рішення, виходячи з наявних на кожному етапі даних, не зважаючи на можливі наслідки, сподіваючись урешті-решт отримати оптимальний розв'язок
* `B` [Гра стрибків](src/algorithms/uncategorized/jump-game) - зворотне відстеження, динамічне програмування (зверху вниз + знизу вгору) та жадібні приклади
* `A` [Задача пакування рюкзака](src/algorithms/sets/knapsack-problem) - приклади "0/1" та "Необмежений"
* `A` [Алгоритм Дейкстри](src/algorithms/graph/dijkstra) - знаходження найкоротшого шляху від однієї вершини графа до всіх інших вершин
* `A` [Алгоритм Прима](src/algorithms/graph/prim) - жадібний алгоритм побудови мінімального кістякового дерева зваженого зв'язного неорієнтованого графа
* `A` [Алгоритм Крускала](src/algorithms/graph/kruskal) - алгоритм побудови мінімального кістякового дерева зваженого неорієнтовного графа
* **Розділяй і володарюй** - важлива парадигма розробки алгоритмів, що полягає в рекурсивному розбитті розв'язуваної задачі на дві або більше підзадачі того ж типу, але меншого розміру, і комбінуванні їх розв'язків для отримання відповіді до вихідного завдання. Розбиття виконуються доти, поки всі підзавдання не стануть елементарними.
* `B` [Двійковий пошук](src/algorithms/search/binary-search) - знаходження заданого значення у впорядкованому масиві
* `B` [Пошук у глибину](src/algorithms/tree/depth-first-search)
* `B` [Пошук у ширину](src/algorithms/tree/breadth-first-search)
* `B` [Гра стрибків](src/algorithms/uncategorized/jump-game) - зворотне відстеження, динамічне програмування (зверху вниз + знизу вгору) та жадібні приклади
* `B` [Швидке піднесення до степеня](src/algorithms/math/fast-powering)
* `A` [Перестановка](src/algorithms/sets/permutations) (з повтореннями та без)
* `A` [Комбінації](src/algorithms/sets/combinations) (з повтореннями та без)
* **Динамічне програмування** - розділ математики, який присвячено теорії і методам розв'язання багатокрокових задач оптимального управління
* `B` [Послідовність Фібоначчі](src/algorithms/math/fibonacci) - класична та закриті версії
* `B` [Гра стрибків](src/algorithms/uncategorized/jump-game) - зворотне відстеження, динамічне програмування (зверху вниз + знизу вгору) та жадібні приклади
* `B` [Проблема унікальних шляхів](src/algorithms/uncategorized/unique-paths) - зворотне відстеження, динамічне програмування та приклади на основі Трикутника Паскаля
* `B` [Дощові тераси](src/algorithms/uncategorized/rain-terraces) - проблема захоплення дощової води (динамічне програмування та версії грубої сили)
* `B` [Завдання про рекурсивні сходи](src/algorithms/uncategorized/recursive-staircase) - підрахунок кількості способів досягти вершини (4 рішення)
* `A` [Відстань Левенштейна](src/algorithms/string/levenshtein-distance) - міра відмінності двох послідовностей символів (рядків)
* `A` [Алгоритм Беллмана — Форда](src/algorithms/graph/bellman-ford) - алгоритм пошуку найкоротшого шляху в зваженому графі
* `A` [Алгоритм Флойда — Воршелла](src/algorithms/graph/floyd-warshall) - знаходження найкоротшого шляху в зваженому графі з додатними або від'ємними вагами ребер (але без від'ємнозначних циклів)
* **Пошук із зворотом** - подібно до грубої сили, намагайтеся генерувати всі можливі рішення, але кожного разу, коли ви створюєте наступне рішення, тестуєте чи він задовольняє всім умовам, і лише потім продовжуєте генерувати наступні рішення. В іншому випадку поверніться назад і рухайтесь далі іншим шляхом пошуку рішення.
* `B` [Гра стрибків](src/algorithms/uncategorized/jump-game) - зворотне відстеження, динамічне програмування (зверху вниз + знизу вгору) та жадібні приклади
* `B` [Проблема унікальних шляхів](src/algorithms/uncategorized/unique-paths) - зворотне відстеження, динамічне програмування та приклади на основі Трикутника Паскаля
* `B` [Булеан](src/algorithms/sets/power-set) - множина всіх підмножин даної множини (бітові та зворотні рішення)
* `A` [Гамільтонів граф](src/algorithms/graph/hamiltonian-cycle) - шлях, що містить кожну вершину графа рівно один раз
* `A` [Задача про вісім ферзів](src/algorithms/uncategorized/n-queens)
* `A` [Задача про хід коня](src/algorithms/uncategorized/knight-tour)
* `A` [Комбінована сума](src/algorithms/sets/combination-sum) - знайти всі комбінації, що утворюють конкретну суму
* **Метод гілок і меж** - один з поширених методів дискретної оптимізації. Метод працює на дереві рішень та визначає принципи роботи конкретних алгоритмів пошуку розв'язків, тобто, є мета-алгоритмом. Для різних задач комбінаторної оптимізації створюють спеціалізовані алгоритми гілок та меж.
## Як користуватися цим репозиторієм
**Встановіть усі залежності**
```
npm install
```
**Запустіть ESLint**
Запустіть для перевірки якості коду
```
npm run lint
```
**Запустіть усі тести**
```
npm test
```
**Запустіть тести за назвою**
```
npm test -- 'LinkedList'
```
**Ігрище**
Ви можете побавитись зі структурами даних та алгоритмами в файлі `./src/playground/playground.js` та писати тести до них в даному файлі `./src/playground/__test__/playground.test.js`.
Для перевірки, чи працює ваш код належним чином запустіть команду:
```
npm test -- 'playground'
```
## Корисна інформація
### Список літератури
[▶ Структури даних та алгоритми на YouTube](https://www.youtube.com/playlist?list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8)
### Асимптотична нотація великого О (нотація Ландау)
*Асимптотична нотація великого О (нотація Ландау)* розповсюджена математична нотація для формального запису асимптотичної поведінки функцій. Широко вживається в теорії складності обчислень, інформатиці та математиці.
![Асимптотична нотація великого О](./assets/big-o-graph.png)
Джерело: [Асимптотична нотація великого О](http://bigocheatsheet.com/).
Нижче наведено список деяких найбільш часто використовуваних позначень нотації Ландаута їх порівняння продуктивності з різними розмірами вхідних даних.
| Нотація Ландау | Обчислення для 10 елементів | Обчислення для 100 елементів | Обчислення для 1000 елементів |
| **Сортування злиттям** | n log(n) | n log(n) | n log(n) | n | Так | |
| **Швидке сортування** | n log(n) | n log(n) | n<sup>2</sup> | log(n) | Ні | Швидке сортування зазвичай виконується на місці з використанням O (log (n)) додаткової пам'яті |
| **Сортування Шелла** | n log(n) | залежить від послідовності проміжків | n (log(n))<sup>2</sup> | 1 | Ні | |
| **Сортування підрахунком** | n + r | n + r | n + r | n + r | Так | Де r - найбільше число в масиві |
| **Сортування за розрядами** | n * k | n * k | n * k | n + k | Так | Де k - довжина найдовшого ключа |
## Патронати проекту
> Ви можете підтримати цей проект через ❤️️ [GitHub](https://github.com/sponsors/trekhleb) або ❤️️ [Patreon](https://www.patreon.com/trekhleb).
[Люди, які підтримують цей проект](https://github.com/trekhleb/javascript-algorithms/blob/master/BACKERS.md) `∑ = 1`
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.