mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-08 12:06:27 +08:00
build
This commit is contained in:
66
ru/docs/chapter_introduction/algorithms_are_everywhere.md
Normal file
66
ru/docs/chapter_introduction/algorithms_are_everywhere.md
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
# 1.1 Алгоритмы повсюду
|
||||
|
||||
Когда мы слышим слово "алгоритм", мы естественным образом думаем о математике. Однако на деле многие алгоритмы не связаны со сложной математикой, а в гораздо большей степени опираются на базовую логику, которую можно увидеть повсюду в повседневной жизни.
|
||||
|
||||
Прежде чем официально перейти к разговору об алгоритмах, стоит поделиться одним любопытным фактом: **ты уже незаметно для себя освоил множество алгоритмов и привык применять их в повседневной жизни**. Ниже я приведу несколько конкретных примеров, чтобы это показать.
|
||||
|
||||
**Пример 1: поиск в словаре**. В английском словаре слова расположены в алфавитном порядке. Предположим, нам нужно найти слово, начинающееся на букву $r$; обычно это делается так, как показано ниже.
|
||||
|
||||
1. Открой словарь примерно посередине и посмотри, с какой буквы начинается страница; предположим, это буква $m$.
|
||||
2. Поскольку в алфавите $r$ идет после $m$, первую половину словаря можно отбросить, и область поиска сузится до второй половины.
|
||||
3. Повторяй шаги `1.` и `2.` до тех пор, пока не найдешь страницу, на которой слово начинается с буквы $r$.
|
||||
|
||||
=== "<1>"
|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<2>"
|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<3>"
|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<4>"
|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "<5>"
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> Рисунок 1-1 Процесс поиска в словаре </p>
|
||||
|
||||
Поиск в словаре, обязательный навык для школьников, на самом деле и есть знаменитый алгоритм "двоичного поиска". С точки зрения структур данных словарь можно рассматривать как отсортированный "массив"; с точки зрения алгоритмов последовательность действий при поиске слова в словаре можно считать алгоритмом "двоичного поиска".
|
||||
|
||||
**Пример 2: упорядочивание карт**. Во время игры в карты нам нужно раскладывать карты в руке по возрастанию; процесс выглядит так, как показано ниже.
|
||||
|
||||
1. Раздели карты на "упорядоченную" и "неупорядоченную" части и предположи, что в начальный момент самая левая карта уже стоит на правильном месте.
|
||||
2. Возьми одну карту из неупорядоченной части и вставь ее в правильную позицию внутри упорядоченной части; после этого две самые левые карты уже будут упорядочены.
|
||||
3. Повторяй шаг `2.` , каждый раз перенося одну карту из неупорядоченной части в упорядоченную, пока все карты не окажутся в порядке.
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> Рисунок 1-2 Процесс сортировки колоды карт </p>
|
||||
|
||||
Описанный выше способ раскладывать карты по сути является алгоритмом "сортировки вставками", который очень эффективен на небольших наборах данных. Во многих языках программирования во встроенных функциях сортировки тоже можно увидеть этот алгоритм.
|
||||
|
||||
**Пример 3: выдача сдачи**. Предположим, в супермаркете мы купили товар на $69$ и дали кассиру $100$, поэтому он должен вернуть нам $31$ сдачи. Этот процесс можно наглядно представить так, как показано на рисунке 1-3.
|
||||
|
||||
1. Доступные варианты - это купюры достоинством меньше $31$, например $1$, $5$, $10$ и $20$.
|
||||
2. Возьми самую большую купюру из доступных, то есть $20$, тогда останется $31 - 20 = 11$.
|
||||
3. Возьми самую большую купюру из оставшихся, то есть $10$, тогда останется $11 - 10 = 1$.
|
||||
4. Возьми самую большую купюру из оставшихся, то есть $1$, тогда останется $1 - 1 = 0$.
|
||||
5. Выдача сдачи завершена, итоговая комбинация: $20 + 10 + 1 = 31$.
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> Рисунок 1-3 Процесс выдачи сдачи </p>
|
||||
|
||||
В описанных шагах на каждом этапе выбирается наилучший вариант из доступных в текущий момент, то есть используется купюра наибольшего номинала; в результате получается рабочая схема выдачи сдачи. С точки зрения структур данных и алгоритмов такой подход называется "жадным" алгоритмом.
|
||||
|
||||
От приготовления еды до межзвездных путешествий почти любое решение задачи связано с алгоритмами. Появление компьютеров позволило нам хранить структуры данных в памяти и писать код, который вызывает CPU и GPU для выполнения алгоритмов. Благодаря этому мы можем переносить реальные задачи в компьютер и решать самые разные сложные проблемы более эффективно.
|
||||
|
||||
!!! tip
|
||||
|
||||
Если ты все еще смутно представляешь себе такие понятия, как структуры данных, алгоритмы, массивы и двоичный поиск, просто продолжай читать. Эта книга постепенно введет тебя в мир понимания структур данных и алгоритмов.
|
||||
20
ru/docs/chapter_introduction/index.md
Normal file
20
ru/docs/chapter_introduction/index.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
comments: true
|
||||
icon: material/calculator-variant-outline
|
||||
---
|
||||
|
||||
# Глава 1. Введение в алгоритмы
|
||||
|
||||
{ class="cover-image" }
|
||||
|
||||
!!! abstract
|
||||
|
||||
Юная девушка легко кружится в танце среди данных, а подол ее платья струится мелодией алгоритмов.
|
||||
|
||||
Она приглашает тебя присоединиться к танцу: следуй за ее шагами и войди в мир алгоритмов, полный логики и красоты.
|
||||
|
||||
## Содержание главы
|
||||
|
||||
- [1.1 Алгоритмы повсюду](algorithms_are_everywhere.md)
|
||||
- [1.2 Что такое структуры данных и алгоритмы](what_is_dsa.md)
|
||||
- [1.3 Резюме](summary.md)
|
||||
28
ru/docs/chapter_introduction/summary.md
Normal file
28
ru/docs/chapter_introduction/summary.md
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
# 1.3 Резюме
|
||||
|
||||
### 1. Ключевые выводы
|
||||
|
||||
- Алгоритмы повсюду встречаются в повседневной жизни и вовсе не являются чем-то далеким и эзотерическим. На деле мы уже давно незаметно для себя освоили множество алгоритмов и используем их для решения самых разных жизненных задач.
|
||||
- Принцип поиска в словаре соответствует алгоритму двоичного поиска. Двоичный поиск воплощает важную алгоритмическую идею "разделяй и властвуй".
|
||||
- Процесс раскладывания карт очень похож на алгоритм сортировки вставками. Сортировка вставками подходит для упорядочивания небольших наборов данных.
|
||||
- Выдача сдачи по шагам по своей сути является жадным алгоритмом, в котором на каждом этапе выбирается лучшее решение в текущей ситуации.
|
||||
- Алгоритм - это набор инструкций или шагов, который решает конкретную задачу за конечное время, а структура данных - это способ, которым компьютер организует и хранит данные.
|
||||
- Структуры данных и алгоритмы тесно связаны. Структуры данных являются основой алгоритмов, а алгоритмы оживляют структуры данных.
|
||||
- Структуры данных и алгоритмы можно сравнить со сборкой конструктора: детали представляют данные, форма деталей и способ их соединения представляют структуру данных, а шаги сборки соответствуют алгоритму.
|
||||
|
||||
### 2. Q & A
|
||||
|
||||
**Q**: Я программист и в повседневной работе никогда не решал задачи "алгоритмами": распространенные алгоритмы уже инкапсулированы в языках программирования, и ими можно пользоваться напрямую. Значит ли это, что рабочие задачи еще не дошли до уровня, где действительно нужны алгоритмы?
|
||||
|
||||
Если сравнить конкретные рабочие навыки с "приемами" в боевых искусствах, то фундаментальные дисциплины скорее напоминают "внутреннюю силу".
|
||||
|
||||
Я считаю, что смысл изучения алгоритмов (и других фундаментальных дисциплин) не в том, чтобы каждый раз реализовывать их с нуля в работе, а в том, чтобы, опираясь на полученные знания, уметь профессионально реагировать и принимать решения при решении задач, тем самым повышая общее качество работы. Вот простой пример: в каждом языке программирования есть встроенная функция сортировки.
|
||||
|
||||
- Если мы не изучали структуры данных и алгоритмы, то для любых данных, скорее всего, просто отдали бы их этой функции сортировки. Все работает гладко, производительность хорошая, и на первый взгляд никаких проблем нет.
|
||||
- Но если мы изучали алгоритмы, то знаем, что временная сложность встроенной сортировки равна $O(n \log n)$ ; однако если данные состоят из целых чисел фиксированной разрядности (например, номеров студентов), можно воспользоваться более эффективной "поразрядной сортировкой", снизив сложность до $O(nk)$ , где $k$ - число разрядов. Когда объем данных очень велик, сэкономленное время выполнения может принести заметную пользу, например снизить издержки и улучшить пользовательский опыт.
|
||||
|
||||
В инженерной практике огромное количество задач трудно довести до оптимального решения, и многие из них решаются лишь "примерно". Сложность задачи зависит, с одной стороны, от ее собственной природы, а с другой - от запаса знаний человека, который на нее смотрит. Чем полнее знания и чем больше опыт, тем глубже получается анализ задачи и тем изящнее ее можно решить.
|
||||
65
ru/docs/chapter_introduction/what_is_dsa.md
Normal file
65
ru/docs/chapter_introduction/what_is_dsa.md
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
# 1.2 Что такое алгоритм
|
||||
|
||||
## 1.2.1 Определение алгоритма
|
||||
|
||||
<u>Алгоритм (algorithm)</u> - это набор инструкций или шагов, который решает конкретную задачу за конечное время. Он обладает следующими свойствами.
|
||||
|
||||
- Задача четко определена и имеет ясные определения входных и выходных данных.
|
||||
- Алгоритм осуществим и может быть выполнен за конечное число шагов, времени и памяти.
|
||||
- Каждый шаг имеет однозначный смысл, и при одинаковых входных данных и условиях выполнения результат всегда будет одинаковым.
|
||||
|
||||
## 1.2.2 Определение структуры данных
|
||||
|
||||
<u>Структура данных (data structure)</u> - это способ организации и хранения данных, охватывающий само содержимое данных, связи между данными и методы работы с ними. У нее есть следующие цели проектирования.
|
||||
|
||||
- Занимать как можно меньше места, чтобы экономить память компьютера.
|
||||
- Выполнять операции над данными как можно быстрее, включая доступ, добавление, удаление, обновление и т. д.
|
||||
- Предоставлять компактное представление данных и логическую информацию, чтобы алгоритмы могли работать эффективно.
|
||||
|
||||
**Проектирование структур данных - это процесс, полный компромиссов**. Если мы хотим улучшить что-то одно, то часто вынуждены уступить в чем-то другом. Ниже приведены два примера.
|
||||
|
||||
- По сравнению с массивами связные списки удобнее для добавления и удаления данных, но жертвуют скоростью доступа к ним.
|
||||
- По сравнению со связными списками графы предоставляют более богатую логическую информацию, но требуют большего объема памяти.
|
||||
|
||||
## 1.2.3 Связь между структурами данных и алгоритмами
|
||||
|
||||
Как показано на рисунке 1-4, структуры данных и алгоритмы тесно связаны и сильно зависят друг от друга; это проявляется в следующих трех аспектах.
|
||||
|
||||
- Структуры данных служат фундаментом алгоритмов. Они дают алгоритмам структурированный способ хранения данных и методы работы с ними.
|
||||
- Алгоритмы оживляют структуры данных. Сами по себе структуры данных лишь хранят информацию, а в сочетании с алгоритмами позволяют решать конкретные задачи.
|
||||
- Алгоритмы обычно можно реализовать на основе разных структур данных, но эффективность выполнения может сильно различаться, поэтому выбор подходящей структуры данных является ключевым.
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> Рисунок 1-4 Связь между структурами данных и алгоритмами </p>
|
||||
|
||||
Структуры данных и алгоритмы похожи на сборку конструктора, показанную на рисунке 1-5. В набор конструктора, помимо множества деталей, входит и подробная инструкция по сборке. Если шаг за шагом следовать этой инструкции, можно собрать красивую модель.
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> Рисунок 1-5 Сборка конструктора </p>
|
||||
|
||||
Подробное соответствие между ними показано в таблице 1-1.
|
||||
|
||||
<p align="center"> Таблица 1-1 Сравнение структур данных и алгоритмов со сборкой конструктора </p>
|
||||
|
||||
<div class="center-table" markdown>
|
||||
|
||||
| Структуры данных и алгоритмы | Сборка конструктора |
|
||||
| ---------------------------- | ------------------------------------------ |
|
||||
| Входные данные | Несобранные детали конструктора |
|
||||
| Структура данных | Организация деталей: форма, размер, способ соединения и т. д. |
|
||||
| Алгоритм | Последовательность шагов по сборке деталей в целевую форму |
|
||||
| Выходные данные | Собранная модель конструктора |
|
||||
|
||||
</div>
|
||||
|
||||
Стоит отметить, что структуры данных и алгоритмы не зависят от конкретного языка программирования. Именно поэтому эта книга может давать реализации на разных языках программирования.
|
||||
|
||||
!!! tip "Принятое сокращение"
|
||||
|
||||
В реальных обсуждениях мы обычно сокращаем выражение "структуры данных и алгоритмы" до просто "алгоритмы". Например, хорошо известные алгоритмические задачи LeetCode на деле одновременно проверяют знания и по структурам данных, и по алгоритмам.
|
||||
Reference in New Issue
Block a user