This commit is contained in:
krahets
2026-03-30 08:17:41 +08:00
parent 68cafe99dd
commit 46bccf0065
484 changed files with 60193 additions and 20315 deletions

View File

@@ -65,8 +65,8 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Noto Sans";--md-code-font:"JetBrains Mono"}</style>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"PT Sans";--md-code-font:"JetBrains Mono"}</style>
@@ -574,7 +574,7 @@
<span class="md-ellipsis">
Глава 1. Знакомство с алгоритмами
Глава 1. Введение в алгоритмы
@@ -596,7 +596,7 @@
<span class="md-nav__icon md-icon"></span>
Глава 1. Знакомство с алгоритмами
Глава 1. Введение в алгоритмы
</label>
@@ -646,7 +646,7 @@
<span class="md-ellipsis">
1.2 Что такое структуры данных и алгоритмы
1.2 Что такое алгоритм
@@ -1181,7 +1181,7 @@
<span class="md-ellipsis">
Глава 4. Массив и связный список
Глава 4. Массивы и списки
@@ -1203,7 +1203,7 @@
<span class="md-nav__icon md-icon"></span>
Глава 4. Массив и связный список
Глава 4. Массивы и списки
</label>
@@ -1309,7 +1309,7 @@
<span class="md-ellipsis">
4.4 Память и кеш *
4.4 Оперативная память и кэш *
@@ -1593,7 +1593,7 @@
<span class="md-ellipsis">
Глава 6. Хеширование
Глава 6. Хеш-таблицы
@@ -1615,7 +1615,7 @@
<span class="md-nav__icon md-icon"></span>
Глава 6. Хеширование
Глава 6. Хеш-таблицы
</label>
@@ -1702,7 +1702,7 @@
<span class="md-ellipsis">
6.3 Хеш-алгоритмы
6.3 Алгоритмы хеширования
@@ -1720,7 +1720,7 @@
<span class="md-ellipsis">
6.3 Хеш-алгоритмы
6.3 Алгоритмы хеширования
@@ -1880,7 +1880,7 @@
<span class="md-ellipsis">
Глава 7. Дерево
Глава 7. Деревья
@@ -1902,7 +1902,7 @@
<span class="md-nav__icon md-icon"></span>
Глава 7. Дерево
Глава 7. Деревья
</label>
@@ -1980,7 +1980,7 @@
<span class="md-ellipsis">
7.3 Представление дерева массивом
7.3 Представление двоичного дерева массивом
@@ -2064,7 +2064,7 @@
<span class="md-ellipsis">
7.6 Резюме
7.6 Краткие итоги
@@ -2227,7 +2227,7 @@
<span class="md-ellipsis">
8.3 Задача Top-K
8.3 Задача Top-k
@@ -2318,7 +2318,7 @@
<span class="md-ellipsis">
Глава 9. Граф
Глава 9. Графы
@@ -2340,7 +2340,7 @@
<span class="md-nav__icon md-icon"></span>
Глава 9. Граф
Глава 9. Графы
</label>
@@ -2390,7 +2390,7 @@
<span class="md-ellipsis">
9.2 Базовые операции над графами
9.2 Базовые операции графа
@@ -2446,7 +2446,7 @@
<span class="md-ellipsis">
9.4 Резюме
9.4 Краткие итоги
@@ -2585,7 +2585,7 @@
<span class="md-ellipsis">
10.2 Точка вставки двоичного поиска
10.2 Двоичный поиск точки вставки
@@ -2613,7 +2613,7 @@
<span class="md-ellipsis">
10.3 Граничные случаи двоичного поиска
10.3 Двоичный поиск границ
@@ -2641,7 +2641,7 @@
<span class="md-ellipsis">
10.4 Стратегия оптимизации через хеширование
10.4 Стратегии оптимизации хеширования
@@ -2669,7 +2669,7 @@
<span class="md-ellipsis">
10.5 Алгоритмы поиска: новый взгляд
10.5 Переосмысление алгоритмов поиска
@@ -2874,7 +2874,7 @@
<span class="md-ellipsis">
11.3 Пузырьковая сортировка
11.3 Сортировка пузырьком
@@ -2902,7 +2902,7 @@
<span class="md-ellipsis">
11.4 Сортировка вставкой
11.4 Сортировка вставками
@@ -3207,7 +3207,7 @@
<span class="md-ellipsis">
12.1 Алгоритмы разделяй и властвуй
12.1 Стратегия разделяй и властвуй
@@ -3235,7 +3235,7 @@
<span class="md-ellipsis">
12.2 Стратегия поиска разделяй и властвуй
12.2 Поисковая стратегия разделяй и властвуй
@@ -3512,7 +3512,7 @@
<span class="md-ellipsis">
13.4 Задача о $n$ ферзях
13.4 Задача о n ферзях
@@ -3653,7 +3653,7 @@
<span class="md-ellipsis">
14.1 Введение в динамическое программирование
14.1 Первое знакомство с динамическим программированием
@@ -3765,7 +3765,7 @@
<span class="md-ellipsis">
14.5 Задача о неограниченном рюкзаке
14.5 Задача о полном рюкзаке
@@ -4410,7 +4410,7 @@
<p>Из этой формулы видно: при фиксированной емкости хеш-таблицы <code>capacity</code> **выходное значение определяет именно хеш-алгоритм <code>hash()</code> **, а значит, именно он определяет распределение пар ключ-значение в хеш-таблице.</p>
<p>Это означает, что для уменьшения вероятности хеш-коллизий нам следует сосредоточиться на проектировании хеш-алгоритма <code>hash()</code> .</p>
<h2 id="631-">6.3.1 &nbsp; Цели хеш-алгоритма<a class="headerlink" href="#631-" title="Permanent link">&para;</a></h2>
<p>Чтобы получить структуру данных хеш-таблицы, которая будет одновременно "быстрой и надежной", хеш-алгоритм должен обладать следующими свойствами.</p>
<p>Чтобы получить структуру данных хеш-таблицы, которая будет одновременно быстрой и надежной, хеш-алгоритм должен обладать следующими свойствами.</p>
<ul>
<li><strong>Детерминированность</strong>: для одинакового входа хеш-алгоритм всегда должен выдавать одинаковый результат. Только так хеш-таблица остается надежной.</li>
<li><strong>Высокая эффективность</strong>: вычисление хеш-значения должно быть достаточно быстрым. Чем меньше вычислительные затраты, тем выше практическая ценность хеш-таблицы.</li>
@@ -5030,7 +5030,7 @@
<p>Следует отметить: если можно гарантировать, что <code>key</code> распределены случайно и равномерно, то выбор простого или составного числа в качестве модуля не так важен - оба варианта способны дать равномерное распределение хеш-значений. Но если в распределении <code>key</code> присутствует периодичность, то взятие по модулю составного числа гораздо легче приводит к кластеризации.</p>
<p>Итак, на практике мы обычно выбираем простое число в качестве модуля, причем это простое число желательно брать достаточно большим, чтобы по возможности убрать периодические закономерности и повысить устойчивость хеш-алгоритма.</p>
<h2 id="633-">6.3.3 &nbsp; Распространенные хеш-алгоритмы<a class="headerlink" href="#633-" title="Permanent link">&para;</a></h2>
<p>Нетрудно заметить, что описанные выше простые хеш-алгоритмы довольно "хрупкие" и далеки от поставленных целей. Например, сложение и XOR подчиняются коммутативному закону, поэтому аддитивный хеш и XOR-хеш не различают строки, состоящие из одних и тех же символов, но в разном порядке. Это может усиливать хеш-коллизии и даже создавать некоторые проблемы безопасности.</p>
<p>Нетрудно заметить, что описанные выше простые хеш-алгоритмы довольно хрупкие и далеки от поставленных целей. Например, сложение и XOR подчиняются коммутативному закону, поэтому аддитивный хеш и XOR-хеш не различают строки, состоящие из одних и тех же символов, но в разном порядке. Это может усиливать хеш-коллизии и даже создавать некоторые проблемы безопасности.</p>
<p>На практике мы обычно используем стандартные хеш-алгоритмы, такие как MD5, SHA-1, SHA-2 и SHA-3. Они могут отображать входные данные произвольной длины в хеш-значения фиксированной длины.</p>
<p>На протяжении почти ста лет хеш-алгоритмы непрерывно развивались и оптимизировались. Одни исследователи старались повысить их производительность, а другие исследователи и хакеры сосредоточивались на поиске уязвимостей в их безопасности. В таблице 6-2 приведены распространенные хеш-алгоритмы, которые часто встречаются в реальных приложениях.</p>
<ul>