Алгосы

This commit is contained in:
ip-ram
2026-01-20 09:34:05 +05:00
parent ff275c125b
commit f9bbb8d83a
16 changed files with 99 additions and 1 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
social/
.obsidian/
Curses/
Rust/

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
Архив/sort_bucket.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
Архив/sort_qsort.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

BIN
Архив/sort_shell.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,2 +1,22 @@
Это алгоритм, в котором элементы входной последовательности просматриваются по одному, и каждый новый поступивший элемент размещается в подходящее место среди ранее упорядоченных элементов. [Сложность алгоритма](Оценка%20сложности%20алгоритма): $O(n^2)$.
#### Алгоритм
На вход алгоритма подаётся последовательность $n$ чисел: $a_1,a_2,...,a_n$. Сортируемые числа также называют ключами. Входная последовательность на практике представляется в виде массива с $n$ элементами. На выходе алгоритм должен вернуть перестановку исходной последовательности $a^`_1,a^`_2,...,a^`_n$, чтобы выполнялось следующее соотношение $a_1^`\leqslant a_2^`\leqslant ... \leqslant a_n^`$ .
В начальный момент отсортированная последовательность пуста. На каждом шаге алгоритма выбирается один из элементов входных данных и помещается на нужную позицию в уже отсортированной последовательности до тех пор, пока набор входных данных не будет исчерпан. В любой момент времени в отсортированной последовательности элементы удовлетворяют требованиям к выходным данным алгоритма.
Данный алгоритм можно ускорить при помощи использования бинарного поиска для нахождения места текущему элементу в отсортированной части. Проблема с долгим сдвигом массива вправо решается при помощи смены указателей.
#### Пример
![[sort_Insertion.gif]]
#### В виде кода
```python
def insertion_sort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i - 1
while j >= 0 and arr[j] > key:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
return arr
```

View File

@@ -1,4 +1,4 @@
сортировка простыми обменами, метод сортировки обменами. По сравнению с другими алгоритмами считается простейшим для понимания и реализации. Эффективен для массивов небольшого размера. n - размер массива, количество элементов массива. [Сложность алгоритма](Оценка%20сложности%20алгоритма): $O(n^2)$.
По сравнению с другими алгоритмами считается простейшим для понимания и реализации. Эффективен для массивов небольшого размера. n - размер массива, количество элементов массива. [Сложность алгоритма](Оценка%20сложности%20алгоритма): $O(n^2)$.
#### Алгоритм
Выполняется некоторое количество проходов по массиву - начиная от начала массива, перебираются пары соседних элементов массива. Если 1-й элемент пары больше 2-го, элементы переставляются (выполняется обмен).

View File

@@ -0,0 +1,3 @@
Свойство [функции](функция), которое объединяет в себе [[Сюрьективность]] и [[Иньективность]] одновременно, для любого x существует только один y.
$\forall x\in X\exists !y\in Y:(x,y)\in F$
![[биекция.png]]

View File

@@ -0,0 +1,25 @@
Алгоритм  в котором сортируемые элементы распределяются между конечным числом отдельных блоков так, чтобы все элементы в каждом следующем по порядку блоке были всегда больше (или меньше), чем в предыдущем. Каждый блок затем сортируется отдельно, либо рекурсивно тем же методом, либо другим. Затем элементы помещаются обратно в массив. Этот тип сортировки может обладать линейным временем исполнения. [Сложность алгоритма](Оценка%20сложности%20алгоритма): $O(n)$.
#### Алгоритм
Если входные элементы подчиняются равномерному закону распределения, то математическое ожидание времени работы алгоритма карманной сортировки является линейным. Это возможно благодаря определенным предположениям о входных данных. При карманной сортировке предполагается, что входные данные равномерно распределены на отрезке \[0, 1).
Идея алгоритма заключается в том, чтобы разбить отрезок \[0, 1) на $n$ одинаковых отрезков (карманов), и разделить по этим карманам $n$ входных величин. Поскольку входные числа равномерно распределены, предполагается, что в каждый карман попадет небольшое количество чисел. Затем последовательно сортируются числа в карманах. Отсортированный массив получается путём последовательного перечисления элементов каждого кармана.
#### Пример
![[sort_bucket.png]]
#### В виде кода
```python
def block_sort(arr, block_size=5):
if not arr:
return arr
min_val = min(arr)
max_val = max(arr)
block_count = (max_val - min_val) // block_size + 1
blocks = [[] for _ in range(block_count)]
for x in arr:
index = (x - min_val) // block_size
blocks[index].append(x)
result = []
for block in blocks:
block.sort()
result.extend(block)
return result
```

View File

@@ -0,0 +1,22 @@
Один из самых быстрых известных универсальных алгоритмов сортировки массивов: в среднем [Сложность алгоритма](Оценка%20сложности%20алгоритма) $O(n\log(n)⁡)$ обменов при упорядочении $n$ элементов, из-за наличия ряда недостатков на практике обычно используется с некоторыми доработками.
#### Алгоритм
Алгоритм состоит из трёх шагов:
1. Выбрать элемент из массива. Назовём его опорным.
2. Разбиение: перераспределение элементов в массиве таким образом, что элементы, меньшие опорного, помещаются перед ним, а большие или равные — после.
3. Рекурсивно применить первые два шага к двум подмассивам слева и справа от опорного элемента. Рекурсия не применяется к массиву, в котором только один элемент или отсутствуют элементы.
В ранних реализациях, как правило, опорным выбирался первый элемент, что снижало производительность на отсортированных массивах. Для улучшения эффективности может выбираться средний, случайный элемент или (для больших массивов) медиана первого, среднего и последнего элементов. Медиана всей последовательности является оптимальным опорным элементом, но её вычисление слишком трудоёмко для использования в сортировке.
#### Пример
![[sort_qsort.gif]]
#### В виде кода
```python
def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quicksort(left) + middle + quicksort(right)
```

View File

@@ -0,0 +1,3 @@
Свойство [функции](функция), которое означает что одинаковый результат возможен только при одинаковых входных данных, для любого x существует только один y.
$\forall x_1,x_2\in X:(x_1\not =x_2=>f(x_1)\not =f(x_2))$
![[иньекция.png]]

View File

@@ -0,0 +1,21 @@
Усовершенствованный вариант сортировки вставками. Идея метода Шелла состоит в сравнении элементов, стоящих не только рядом, но и на определённом расстоянии друг от друга. Иными словами — это сортировка вставками с предварительными «грубыми» проходами. [Сложность алгоритма](Оценка%20сложности%20алгоритма) $O(n^2)$
#### Алгоритм
При сортировке Шелла сначала сравниваются и сортируются между собой значения, стоящие один от другого на некотором расстоянии $d$. После этого процедура повторяется для некоторых меньших значений $d$, а завершается сортировка Шелла упорядочиванием элементов при $d=1$. Эффективность сортировки Шелла в определённых случаях обеспечивается тем, что элементы «быстрее» встают на свои места.
#### Пример
![[sort_shell.gif]]
#### В виде кода
```python
def shell_sort(data: list[int]) -> list[int]:
last_index = len(data)
step = len(data)//2
while step > 0:
for i in range(step, last_index, 1):
j = i
delta = j - step
while delta >= 0 and data[delta] > data[j]:
data[delta], data[j] = data[j], data[delta]
j = delta
delta = j - step
step //= 2
return data
```

View File

@@ -0,0 +1,3 @@
Свойство [функции](функция), которое означает что при любом входе получишь значение, для любого x существует хотя бы один y.
$\forall x\in X\exists y\in Y:f(x)=y$
![[сюрьекция.png]]