First version.

This commit is contained in:
krahets
2026-01-20 15:08:42 +08:00
parent 2213a59ff6
commit 8071daddaa
106 changed files with 11790 additions and 0 deletions
@@ -0,0 +1,57 @@
# Алгоритмы повсюду
Говоря об алгоритмах, естественно вспомнить о математике. Однако на самом деле многие алгоритмы не связаны со сложной математикой, а больше полагаются на базовую логику, которая повсеместно встречается в нашей повседневной жизни.
Прежде чем углубиться в обсуждение алгоритмов, стоит упомянуть интересный факт: **вы уже точно освоили множество алгоритмов и привыкли применять их в повседневной жизни**. Далее приведем несколько конкретных примеров, чтобы подтвердить этот факт.
**Пример 1**: **поиск в словаре**. В словаре все слова упорядочены по алфавиту. Предположим, нам нужно найти слово, начинающееся на букву «r». Обычно для этого нужно выполнить следующие действия (см. рис. 1.1):
1. открыть словарь примерно на половине страниц и посмотреть, какая буква является первой на этой странице, -- предположим, это буква «m»;
2. поскольку в алфавите буква «r» идет после «m», исключаем первую половину словаря, и область поиска сужается до второй половины;
3. продолжаем повторять шаги 1 и 2, пока не найдем страницу, где первой буквой слов будет «r».
=== "<1>"
![Этапы поиска в словаре. Шаг 1](../assets/media/image52.jpeg)
=== "<2>"
![Продолжение. Шаги 2--3](../assets/media/image54.jpeg)
=== "<3>"
![Продолжение. Шаги 2--3](../assets/media/image56.jpeg)
=== "<4>"
![Окончание. Шаги 4--5](../assets/media/image58.jpeg)
=== "<5>"
![Окончание. Шаги 4--5](../assets/media/image60.jpeg)
Навык поиска в словаре, которым владеет каждый школьник, на самом деле является известным алгоритмом двоичного поиска. С точки зрения структуры данных словарь можно рассматривать как отсортированный массив. С точки зрения алгоритма последовательность операций по поиску в словаре можно считать двоичным поиском.
**Пример 2**: **упорядочивание карт**. Во время игры в карты необходимо каждый раз упорядочивать карты в руке от меньшего к большему. Для этого нужно выполнить следующие действия (см. рис. 1.2):
1. разделить карты на упорядоченную и неупорядоченную части, предполагая, что изначально самая левая карта уже упорядочена;
2. из неупорядоченной части извлечь одну карту и вставить ее в правильное место в упорядоченной части. После этого две самые левые карты станут упорядоченными;
3. повторять шаг 2, каждый раз перемещая одну карту из неупорядоченной части в упорядоченную, пока все карты не станут упорядоченными.
![Этапы упорядочивания карт](../assets/media/image62.jpeg)
Метод упорядочивания карт по своей сути является алгоритмом сортировки вставками, который весьма эффективен при обработке небольших наборов данных. Многие функции сортировки в библиотеках программирования используют именно этот алгоритм.
**Пример 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 руб.
![Этапы выдачи сдачи](../assets/media/image64.jpeg)
В этих шагах мы на каждом этапе выбираем наилучший вариант (используя купюры наибольшего номинала), в итоге получая оптимальную схему сдачи. С точки зрения структуры данных и алгоритмов этот метод по своей сути является жадным алгоритмом.
От приготовления блюда до межзвездных путешествий − решение практически любой задачи неразрывно связано с алгоритмами. Появление компьютеров позволило нам с помощью программирования хранить структуры данных в памяти, а также писать код для вызовов к центральному и графическому процессору для выполнения алгоритмов. Таким образом, мы можем переносить задачи из реальной жизни в компьютер, решая различные сложные проблемы более эффективно.
!!! tip
<!-- 🔴 俄文版缺失此段落 -->
<!-- 中文原文:如果你对数据结构、算法、数组和二分查找等概念仍感到一知半解,请继续往下阅读,本书将引导你迈入数据结构与算法的知识殿堂。 -->
+9
View File
@@ -0,0 +1,9 @@
# Введение в алгоритмы
![Введение в алгоритмы](../assets/covers/chapter_introduction.jpg)
!!! abstract
Девушка танцует, переплетаясь с данными, на подоле её платья развеваются мелодии алгоритмов.
Она приглашает вас на танец, следуйте за её шагами и войдите в мир алгоритмов, полный логики и красоты.
+30
View File
@@ -0,0 +1,30 @@
# Резюме
### Основные выводы
- Алгоритмы повсеместно присутствуют в нашей повседневной жизни и не являются недосягаемыми сложными знаниями. На самом деле мы уже освоили множество алгоритмов, которые помогают решать различные жизненные задачи.
- Принцип поиска в словаре соответствует алгоритму двоичного поиска. Бинарный поиск иллюстрирует важную идею алгоритмов «разделяй и властвуй».
- Процесс сортировки карт в колоде очень похож на алгоритм сортировки вставками, который хорошо подходит для сортировки небольших наборов данных.
- Процесс размена валюты по своей сути является жадным алгоритмом, в котором на каждом этапе принимается наилучшее на данный момент решение.
- Алгоритм представляет собой набор инструкций или шагов, предназначенных для решения конкретной задачи в ограниченное время, а структура данных -- это способ организации и хранения данных в компьютере.
- Структуры данных и алгоритмы тесно связаны. Структуры данных являются основой для алгоритмов, а алгоритмы оживляют структуры данных.
- Структуры данных и алгоритмы можно сравнить с конструктором: детали конструктора представляют данные, их форма и способы соединения -- структуры данных, а этапы сборки конструктора соответствуют алгоритмам.
### Вопросы и ответы
**Вопрос**. Я программист, и я никогда не использовал алгоритмы для решения задач в своей повседневной работе, поскольку часто используемые алгоритмы уже встроены в языки программирования и их можно использовать напрямую. Означает ли это, что задачи, с которыми мы сталкиваемся на работе, не требуют применения алгоритмов?
Если сравнить конкретные профессиональные навыки с приемами в боевых искусствах, то базовые дисциплины скорее напоминают «внутреннюю силу».
Я считаю, что изучение алгоритмов (и других базовых дисциплин) важно не для того, чтобы реализовывать их с нуля в работе, а для того, чтобы на основе полученных знаний принимать профессиональные решения и оценки при решении задач, тем самым повышая общее качество работы. Простой пример: каждый язык программирования имеет встроенные функции сортировки.
- Если бы мы не изучали структуры данных и алгоритмы, то, получив любые данные, мы, возможно, просто передали бы их этой функции сортировки. Все работает гладко, производительность хорошая, и на первый взгляд проблем нет.
- Однако если мы изучили алгоритмы, то знаем, что временная сложность встроенной функции сортировки составляет $O(n \log n)$. Если же данные представлены целыми числами фиксированной разрядности (например, номерами студентов), то можно использовать более эффективный метод поразрядной сортировки, снизив временную сложность до $O(nk)$, где $k$ -- это количество разрядов. При больших объемах данных экономия времени выполнения может привести к значительным преимуществам, таким как снижение затрат и улучшение пользовательского опыта.
В инженерной практике множество задач трудно решить оптимальным образом, и многие из них решаются «как-то». Сложность задачи зависит как от ее природы, так и от уровня знаний и опыта человека, который ее анализирует. Чем более полными знаниями и большим опытом обладает человек, тем глубже он может проанализировать проблему и тем изящнее может быть ее решение.
@@ -0,0 +1,49 @@
# Что такое алгоритм
## Определение алгоритма
*Алгоритм* -- это набор инструкций или шагов, предназначенных для решения конкретной задачи за ограниченное время, обладающий следующими свойствами:
- задача четко определена, включает ясные определения входных и выходных данных;
- обладает осуществимостью, может быть выполнен за ограниченное количество шагов, времени и памяти;
- каждый шаг имеет определенное значение, при одинаковых входных данных и условиях выполнения результат всегда будет одинаковым.
## Определение структуры данных
*Структура данных* -- это способ организации и хранения данных, включающий содержимое данных, их взаимосвязи и методы операций с ними. Структура данных преследует следующие цели:
- минимизацию занимаемого пространства для экономии памяти компьютера;
- максимально быструю обработку данных, включая доступ, добавление, удаление и обновление данных;
- обеспечение простого представления данных и логической информации для эффективного выполнения алгоритмов.
**Проектирование структуры данных** -- **это процесс, полный компромиссов**. Если вы хотите улучшить один аспект, часто приходится идти на уступки в другом. Приведем два примера.
- Связный список, по сравнению с массивом, более удобен для добавления и удаления данных, но имеет проблемы со скоростью доступа к данным.
- Граф, по сравнению со связным списком, предоставляет более богатую логическую информацию, но требует большего объема памяти.
## Взаимосвязь структур данных и алгоритмов
Структуры данных и алгоритмы тесно взаимосвязаны, что проявляется в следующих трех аспектах (см. рис. 1.4):
- структуры данных являются основой алгоритмов. Они обеспечивают структурированное хранение данных и методы их обработки;
- алгоритмы оживляют структуры данных. Сами по себе структуры данных лишь хранят информацию, но в сочетании с алгоритмами они позволяют решать конкретные задачи;
- алгоритмы можно реализовать на основе различных структур данных, однако эффективность их выполнения может значительно различаться. Поэтому выбор подходящей структуры данных является ключевым фактором.
![Взаимосвязь структур данных и алгоритмов](../assets/media/image66.jpeg)
Структуры данных и алгоритмы подобны конструктору, как показано на рис. 1.5. Комплект конструктора, помимо множества деталей, содержит также подробную инструкцию по сборке. Следуя этой инструкции шаг за шагом, можно собрать красивую модель.
![Сборка конструктора](../assets/media/image67.jpeg)
Подробное описание аналогии с конструктором представлено в табл. 1.1.
**Таблица 1.1.** Сравнение структур данных и алгоритмов с конструктором
| Структуры данных и алгоритмы | Конструктор |
| -------------- | ---------------------------------------- |
| Входные данные | Несобранные детали конструктора |
| Структура данных | Организация деталей конструктора, включая форму, размер, способы соединения и т. д. |
| Алгоритм | Последовательность действий по сборке деталей в целевую модель |
| Выходные данные | Собранная модель конструктора |
Стоит отметить, что структуры данных и алгоритмы не зависят от языка программирования. Именно поэтому данная книга предлагает их реализации на различных языках.