mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-28 19:07:14 +00:00
deploy
This commit is contained in:
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -576,7 +576,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
|
||||
@@ -598,7 +598,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -658,7 +658,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.2 Что такое структуры данных и алгоритмы
|
||||
1.2 Что такое алгоритм
|
||||
|
||||
|
||||
|
||||
@@ -1193,7 +1193,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
|
||||
@@ -1215,7 +1215,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1321,7 +1321,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
4.4 Память и кеш *
|
||||
4.4 Оперативная память и кэш *
|
||||
|
||||
|
||||
|
||||
@@ -1603,7 +1603,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
|
||||
@@ -1625,7 +1625,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1703,7 +1703,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.3 Хеш-алгоритмы
|
||||
6.3 Алгоритмы хеширования
|
||||
|
||||
|
||||
|
||||
@@ -1798,7 +1798,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
|
||||
@@ -1820,7 +1820,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1898,7 +1898,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.3 Представление дерева массивом
|
||||
7.3 Представление двоичного дерева массивом
|
||||
|
||||
|
||||
|
||||
@@ -1982,7 +1982,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.6 Резюме
|
||||
7.6 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2145,7 +2145,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.3 Задача Top-K
|
||||
8.3 Задача Top-k
|
||||
|
||||
|
||||
|
||||
@@ -2236,7 +2236,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
|
||||
@@ -2258,7 +2258,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -2308,7 +2308,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.2 Базовые операции над графами
|
||||
9.2 Базовые операции графа
|
||||
|
||||
|
||||
|
||||
@@ -2364,7 +2364,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.4 Резюме
|
||||
9.4 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2503,7 +2503,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Точка вставки двоичного поиска
|
||||
10.2 Двоичный поиск точки вставки
|
||||
|
||||
|
||||
|
||||
@@ -2531,7 +2531,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Граничные случаи двоичного поиска
|
||||
10.3 Двоичный поиск границ
|
||||
|
||||
|
||||
|
||||
@@ -2559,7 +2559,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.4 Стратегия оптимизации через хеширование
|
||||
10.4 Стратегии оптимизации хеширования
|
||||
|
||||
|
||||
|
||||
@@ -2587,7 +2587,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Алгоритмы поиска: новый взгляд
|
||||
10.5 Переосмысление алгоритмов поиска
|
||||
|
||||
|
||||
|
||||
@@ -2792,7 +2792,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.3 Пузырьковая сортировка
|
||||
11.3 Сортировка пузырьком
|
||||
|
||||
|
||||
|
||||
@@ -2820,7 +2820,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.4 Сортировка вставкой
|
||||
11.4 Сортировка вставками
|
||||
|
||||
|
||||
|
||||
@@ -3125,7 +3125,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.1 Алгоритмы разделяй и властвуй
|
||||
12.1 Стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3153,7 +3153,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.2 Стратегия поиска разделяй и властвуй
|
||||
12.2 Поисковая стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3430,7 +3430,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.4 Задача о $n$ ферзях
|
||||
13.4 Задача о n ферзях
|
||||
|
||||
|
||||
|
||||
@@ -3571,7 +3571,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.1 Введение в динамическое программирование
|
||||
14.1 Первое знакомство с динамическим программированием
|
||||
|
||||
|
||||
|
||||
@@ -3683,7 +3683,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.5 Задача о неограниченном рюкзаке
|
||||
14.5 Задача о полном рюкзаке
|
||||
|
||||
|
||||
|
||||
@@ -4265,62 +4265,62 @@
|
||||
|
||||
<!-- Page content -->
|
||||
<h1 id="11">1.1 Алгоритмы повсюду<a class="headerlink" href="#11" title="Permanent link">¶</a></h1>
|
||||
<p>Когда мы слышим слово "алгоритм", мы естественным образом думаем о математике. Однако на деле многие алгоритмы не связаны со сложной математикой, а в гораздо большей степени опираются на базовую логику, которую можно увидеть повсюду в повседневной жизни.</p>
|
||||
<p>Прежде чем официально перейти к разговору об алгоритмах, стоит поделиться одним любопытным фактом: <strong>ты уже незаметно для себя освоил множество алгоритмов и привык применять их в повседневной жизни</strong>. Ниже я приведу несколько конкретных примеров, чтобы это показать.</p>
|
||||
<p><strong>Пример 1: поиск в словаре</strong>. В английском словаре слова расположены в алфавитном порядке. Предположим, нам нужно найти слово, начинающееся на букву <span class="arithmatex">\(r\)</span>; обычно это делается так, как показано ниже.</p>
|
||||
<p>Говоря об алгоритмах, естественно вспомнить о математике. Однако на самом деле многие алгоритмы не связаны со сложной математикой, а больше полагаются на базовую логику, которая повсеместно встречается в нашей повседневной жизни.</p>
|
||||
<p>Прежде чем углубиться в обсуждение алгоритмов, стоит упомянуть интересный факт: <strong>вы уже точно освоили множество алгоритмов и привыкли применять их в повседневной жизни</strong>. Далее приведем несколько конкретных примеров, чтобы подтвердить этот факт.</p>
|
||||
<p><strong>Пример 1: поиск в словаре</strong>. В словаре все слова упорядочены по алфавиту. Предположим, нам нужно найти слово, начинающееся на букву <span class="arithmatex">\(r\)</span>; обычно для этого нужно выполнить следующие действия.</p>
|
||||
<ol>
|
||||
<li>Открой словарь примерно посередине и посмотри, с какой буквы начинается страница; предположим, это буква <span class="arithmatex">\(m\)</span>.</li>
|
||||
<li>Поскольку в алфавите <span class="arithmatex">\(r\)</span> идет после <span class="arithmatex">\(m\)</span>, первую половину словаря можно отбросить, и область поиска сузится до второй половины.</li>
|
||||
<li>Повторяй шаги <code>1.</code> и <code>2.</code> до тех пор, пока не найдешь страницу, на которой слово начинается с буквы <span class="arithmatex">\(r\)</span>.</li>
|
||||
<li>Откройте словарь примерно на половине страниц и посмотрите, какая буква является первой на этой странице; предположим, это буква <span class="arithmatex">\(m\)</span>.</li>
|
||||
<li>Поскольку в алфавите буква <span class="arithmatex">\(r\)</span> идет после <span class="arithmatex">\(m\)</span>, исключаем первую половину словаря, и область поиска сужается до второй половины.</li>
|
||||
<li>Продолжайте повторять шаги <code>1.</code> и <code>2.</code> , пока не найдете страницу, где первой буквой слов будет <span class="arithmatex">\(r\)</span>.</li>
|
||||
</ol>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="1:5"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1"><1></label><label for="__tabbed_1_2"><2></label><label for="__tabbed_1_3"><3></label><label for="__tabbed_1_4"><4></label><label for="__tabbed_1_5"><5></label></div>
|
||||
<div class="tabbed-content">
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="Процесс поиска в словаре" class="animation-figure" src="../algorithms_are_everywhere.assets/binary_search_dictionary_step1.png" /></p>
|
||||
<p><img alt="Этапы поиска в словаре. Шаг 1" class="animation-figure" src="../algorithms_are_everywhere.assets/binary_search_dictionary_step1.png" /></p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="Бинарный поиск в словаре, шаг 2" class="animation-figure" src="../algorithms_are_everywhere.assets/binary_search_dictionary_step2.png" /></p>
|
||||
<p><img alt="Этапы поиска в словаре. Шаг 2" class="animation-figure" src="../algorithms_are_everywhere.assets/binary_search_dictionary_step2.png" /></p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="Бинарный поиск в словаре, шаг 3" class="animation-figure" src="../algorithms_are_everywhere.assets/binary_search_dictionary_step3.png" /></p>
|
||||
<p><img alt="Этапы поиска в словаре. Шаг 3" class="animation-figure" src="../algorithms_are_everywhere.assets/binary_search_dictionary_step3.png" /></p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="Бинарный поиск в словаре, шаг 4" class="animation-figure" src="../algorithms_are_everywhere.assets/binary_search_dictionary_step4.png" /></p>
|
||||
<p><img alt="Этапы поиска в словаре. Шаг 4" class="animation-figure" src="../algorithms_are_everywhere.assets/binary_search_dictionary_step4.png" /></p>
|
||||
</div>
|
||||
<div class="tabbed-block">
|
||||
<p><img alt="Бинарный поиск в словаре, шаг 5" class="animation-figure" src="../algorithms_are_everywhere.assets/binary_search_dictionary_step5.png" /></p>
|
||||
<p><img alt="Этапы поиска в словаре. Шаг 5" class="animation-figure" src="../algorithms_are_everywhere.assets/binary_search_dictionary_step5.png" /></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p align="center"> Рисунок 1-1 Процесс поиска в словаре </p>
|
||||
<p align="center"> Рисунок 1-1 Этапы поиска в словаре. Шаг 1 </p>
|
||||
|
||||
<p>Поиск в словаре, обязательный навык для школьников, на самом деле и есть знаменитый алгоритм "двоичного поиска". С точки зрения структур данных словарь можно рассматривать как отсортированный "массив"; с точки зрения алгоритмов последовательность действий при поиске слова в словаре можно считать алгоритмом "двоичного поиска".</p>
|
||||
<p><strong>Пример 2: упорядочивание карт</strong>. Во время игры в карты нам нужно раскладывать карты в руке по возрастанию; процесс выглядит так, как показано ниже.</p>
|
||||
<p>Навык поиска в словаре, которым владеет каждый школьник, на самом деле является известным алгоритмом двоичного поиска. С точки зрения структуры данных словарь можно рассматривать как отсортированный массив; с точки зрения алгоритма последовательность операций по поиску в словаре можно считать двоичным поиском.</p>
|
||||
<p><strong>Пример 2: упорядочивание карт</strong>. Во время игры в карты необходимо каждый раз упорядочивать карты в руке от меньшего к большему. Для этого нужно выполнить следующие действия.</p>
|
||||
<ol>
|
||||
<li>Раздели карты на "упорядоченную" и "неупорядоченную" части и предположи, что в начальный момент самая левая карта уже стоит на правильном месте.</li>
|
||||
<li>Возьми одну карту из неупорядоченной части и вставь ее в правильную позицию внутри упорядоченной части; после этого две самые левые карты уже будут упорядочены.</li>
|
||||
<li>Повторяй шаг <code>2.</code> , каждый раз перенося одну карту из неупорядоченной части в упорядоченную, пока все карты не окажутся в порядке.</li>
|
||||
<li>Разделите карты на упорядоченную и неупорядоченную части, предполагая, что изначально самая левая карта уже упорядочена.</li>
|
||||
<li>Из неупорядоченной части извлеките одну карту и вставьте ее в правильное место в упорядоченной части; после этого две самые левые карты станут упорядоченными.</li>
|
||||
<li>Повторяйте шаг <code>2.</code> , каждый раз перемещая одну карту из неупорядоченной части в упорядоченную, пока все карты не станут упорядоченными.</li>
|
||||
</ol>
|
||||
<p><img alt="Процесс сортировки колоды карт" class="animation-figure" src="../algorithms_are_everywhere.assets/playing_cards_sorting.png" /></p>
|
||||
<p align="center"> Рисунок 1-2 Процесс сортировки колоды карт </p>
|
||||
<p><img alt="Этапы упорядочивания карт" class="animation-figure" src="../algorithms_are_everywhere.assets/playing_cards_sorting.png" /></p>
|
||||
<p align="center"> Рисунок 1-2 Этапы упорядочивания карт </p>
|
||||
|
||||
<p>Описанный выше способ раскладывать карты по сути является алгоритмом "сортировки вставками", который очень эффективен на небольших наборах данных. Во многих языках программирования во встроенных функциях сортировки тоже можно увидеть этот алгоритм.</p>
|
||||
<p><strong>Пример 3: выдача сдачи</strong>. Предположим, в супермаркете мы купили товар на <span class="arithmatex">\(69\)</span> и дали кассиру <span class="arithmatex">\(100\)</span>, поэтому он должен вернуть нам <span class="arithmatex">\(31\)</span> сдачи. Этот процесс можно наглядно представить так, как показано на рисунке 1-3.</p>
|
||||
<p>Метод упорядочивания карт по своей сути является алгоритмом сортировки вставками, который весьма эффективен при обработке небольших наборов данных. Многие функции сортировки в библиотеках программирования используют именно этот алгоритм.</p>
|
||||
<p><strong>Пример 3: сдача</strong>. Предположим, что в супермаркете мы купили товар стоимостью <span class="arithmatex">\(69\)</span> руб. и дали кассиру купюру в <span class="arithmatex">\(100\)</span> руб. Кассир должен вернуть нам <span class="arithmatex">\(31\)</span> руб. Для этого ему нужно выполнить следующие действия.</p>
|
||||
<ol>
|
||||
<li>Доступные варианты - это купюры достоинством меньше <span class="arithmatex">\(31\)</span>, например <span class="arithmatex">\(1\)</span>, <span class="arithmatex">\(5\)</span>, <span class="arithmatex">\(10\)</span> и <span class="arithmatex">\(20\)</span>.</li>
|
||||
<li>Возьми самую большую купюру из доступных, то есть <span class="arithmatex">\(20\)</span>, тогда останется <span class="arithmatex">\(31 - 20 = 11\)</span>.</li>
|
||||
<li>Возьми самую большую купюру из оставшихся, то есть <span class="arithmatex">\(10\)</span>, тогда останется <span class="arithmatex">\(11 - 10 = 1\)</span>.</li>
|
||||
<li>Возьми самую большую купюру из оставшихся, то есть <span class="arithmatex">\(1\)</span>, тогда останется <span class="arithmatex">\(1 - 1 = 0\)</span>.</li>
|
||||
<li>Выдача сдачи завершена, итоговая комбинация: <span class="arithmatex">\(20 + 10 + 1 = 31\)</span>.</li>
|
||||
<li>Варианты выбора - это купюры номиналом меньше <span class="arithmatex">\(31\)</span> руб. Пусть у нас имеются номиналы <span class="arithmatex">\(1\)</span> , <span class="arithmatex">\(5\)</span> , <span class="arithmatex">\(10\)</span> и <span class="arithmatex">\(20\)</span> руб.</li>
|
||||
<li>Возьмем самую крупную доступную купюру в <span class="arithmatex">\(20\)</span> руб. Остаток сдачи составит <span class="arithmatex">\(31 - 20 = 11\)</span> руб.</li>
|
||||
<li>Возьмем самую крупную из оставшихся купюр в <span class="arithmatex">\(10\)</span> руб. Остаток составит <span class="arithmatex">\(11 - 10 = 1\)</span> руб.</li>
|
||||
<li>Возьмем самую крупную из оставшихся купюр в <span class="arithmatex">\(1\)</span> руб. Остаток составит <span class="arithmatex">\(1 - 1 = 0\)</span> руб.</li>
|
||||
<li>Завершим выдачу сдачи, схема: <span class="arithmatex">\(20 + 10 + 1 = 31\)</span> руб.</li>
|
||||
</ol>
|
||||
<p><img alt="Процесс выдачи сдачи" class="animation-figure" src="../algorithms_are_everywhere.assets/greedy_change.png" /></p>
|
||||
<p align="center"> Рисунок 1-3 Процесс выдачи сдачи </p>
|
||||
<p><img alt="Этапы выдачи сдачи" class="animation-figure" src="../algorithms_are_everywhere.assets/greedy_change.png" /></p>
|
||||
<p align="center"> Рисунок 1-3 Этапы выдачи сдачи </p>
|
||||
|
||||
<p>В описанных шагах на каждом этапе выбирается наилучший вариант из доступных в текущий момент, то есть используется купюра наибольшего номинала; в результате получается рабочая схема выдачи сдачи. С точки зрения структур данных и алгоритмов такой подход называется "жадным" алгоритмом.</p>
|
||||
<p>От приготовления еды до межзвездных путешествий почти любое решение задачи связано с алгоритмами. Появление компьютеров позволило нам хранить структуры данных в памяти и писать код, который вызывает CPU и GPU для выполнения алгоритмов. Благодаря этому мы можем переносить реальные задачи в компьютер и решать самые разные сложные проблемы более эффективно.</p>
|
||||
<p>В этих шагах мы на каждом этапе выбираем наилучший вариант, используя купюры наибольшего номинала, и в итоге получаем рабочую схему сдачи. С точки зрения структуры данных и алгоритмов этот метод по своей сути является жадным алгоритмом.</p>
|
||||
<p>От приготовления блюда до межзвездных путешествий решение практически любой задачи неразрывно связано с алгоритмами. Появление компьютеров позволило нам с помощью программирования хранить структуры данных в памяти, а также писать код для вызовов к CPU и GPU для выполнения алгоритмов. Таким образом, мы можем переносить задачи из реальной жизни в компьютер и решать различные сложные проблемы более эффективно.</p>
|
||||
<div class="admonition tip">
|
||||
<p class="admonition-title">Tip</p>
|
||||
<p>Если ты все еще смутно представляешь себе такие понятия, как структуры данных, алгоритмы, массивы и двоичный поиск, просто продолжай читать. Эта книга постепенно введет тебя в мир понимания структур данных и алгоритмов.</p>
|
||||
<p>Если представление о структурах данных, алгоритмах, массивах и двоичном поиске пока остается расплывчатым, просто продолжайте читать. Эта книга постепенно введет вас в мир структур данных и алгоритмов.</p>
|
||||
</div>
|
||||
|
||||
<!-- Source file information -->
|
||||
@@ -4368,7 +4368,7 @@ aria-label="Нижний колонтитул"
|
||||
<a
|
||||
href="../what_is_dsa/"
|
||||
class="md-footer__link md-footer__link--next"
|
||||
aria-label="Вперед: 1.2 Что такое структуры данных и алгоритмы"
|
||||
aria-label="Вперед: 1.2 Что такое алгоритм"
|
||||
rel="next"
|
||||
>
|
||||
<div class="md-footer__title">
|
||||
@@ -4376,7 +4376,7 @@ aria-label="Нижний колонтитул"
|
||||
Вперед
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
1.2 Что такое структуры данных и алгоритмы
|
||||
1.2 Что такое алгоритм
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-footer__button md-icon">
|
||||
|
||||
Reference in New Issue
Block a user