Files
hello-algo/ru/chapters/chapter_00.md
2026-03-25 16:54:42 +08:00

338 lines
29 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Введение
![](ru/docs/assets/media/image31.jpeg){width="4.60417760279965in" height="5.958333333333333in"}
1. **О книге**
> Этот проект задуман как открытое, бесплатное и дружелюбное к новичкам введение в структуры данных и алгоритмы.
1. В книге используются анимационные иллюстрации. Материал изложен ясно и последовательно, что облегчает освоение и помогает начинаю- щим построить «карту знаний» по структурам данных и алгоритмам.
2. Исходный код можно запустить одним кликом, что позволяет трениро- ваться, развивать навыки программирования и формировать понима- ние принципов работы алгоритмов и реализации структур данных на фундаментальном уровне.
3. Мы призываем к взаимопомощи читателей: задавайте вопросы и дели- тесь идеями в комментариях. Обсуждения помогают двигаться вперед всем вместе.
### Целевая аудитория
> Если вы новичок в алгоритмах, никогда с ними не сталкивались или у вас есть некоторый опыт решения задач, но еще нет четкого понимания структур дан- ных и алгоритмов, эта книга создана специально для вас!
>
> Если у вас уже есть определенный опыт решения задач и вы знакомы с боль- шинством типов задач, эта книга поможет вам освежить и систематизировать знания об алгоритмах. Исходный код может служить набором инструментов для решения задач или алгоритмическим словарем.
>
> Если вы владеете алгоритмами на экспертном уровне, мы будем рады ва- шим ценным советам или совместному участию в создании книги.
### Структура книги
> Основное содержание книги представлено на рис. 0.1.
1. **Анализ сложности**: критерии и методы оценки структур данных и ал- горитмов. Методы расчета временной и пространственной сложности, распространенные типы, примеры и т. д.
> ![](ru/docs/assets/media/image33.png)**Структуры данных**
>
> **Структуры данных**
>
> **Массивы и списки**
>
> **Стек**
>
> **[и]{.smallcaps} очередь**
>
> **Хеш- таблицы**
>
> Логическая и физическая структура Базовые типы данных
>
> Цифровое и символьное кодирование
>
> Способы непрерывного и распределенного хранения Методы работы, преимущества
>
> [и]{.smallcaps} недостатки двух способов
>
> Реализация списка на основе динамического массива
>
> Память и кеш в компьютере
>
> Последний пришел -- первый вышел, первый пришел -- первый вышел, двусторонняя очередь
>
> Реализация на основе массива и связного списка
>
> Принцип работы хеш-таблицы, реализация на основе массива
>
> Хеш-коллизии, цепная и открытая адресация Назначение и цели хеш-алгоритмов
>
> Идеальное, совершенное, полное, сбалансированное
>
> двоичное дерево
>
> **Анализ сложности**
>
> **Итерация и рекурсия**
>
> **Временная сложность**
>
> **Пространственная сложность**
>
> **Поиск**
>
> Циклы for и while, вложенные циклы
>
> Стек вызовов рекурсии, хвостовая рекурсия, дерево рекурсии
>
> Сравнение итерации и рекурсии
>
> Асимптотическая верхняя граница
>
> Методы вычисления, основные типы
>
> Наихудшая, наилучшая, средняя временная сложность
>
> Методы вычисления, основные типы Компромисс между временем
>
> и пространством
>
> Перебор: линейный поиск, поиск в ширину и глубину
>
> Адаптивный поиск: двоичный поиск, хеш-поиск, поиск по дереву
>
> Выбор алгоритма поиска
>
> Местность, устойчивость, адаптивность, основанность на сравнении
>
> Перебор: сортировка выбором, пузырьком, вставками
**Деревья**
**Куча**
**Графы**
https://github.com/krahets/hello-algo
> Представление связным списком и массивом, сравнение Обход в ширину; прямой, симметричный и обратный порядок Двоичное дерево поиска
>
> АВЛ-дерево
>
> ![](ru/docs/assets/media/image35.png)Минимальная и максимальная куча, **Алгоритмы**
>
> очередь с приоритетом
>
> Реализация кучи на основе массива, операция построения кучи
>
> Задача о k наибольших элементов
>
> Ориентированный, связный и взвешенный графы Список и матрица смежности, их сравнение Обход в ширину и в глубину
>
> **Сортировка**
>
> **Разделяй и властвуй**
>
> **Поиск**
>
> **с возвратом**
>
> **Динамическое программирование**
>
> **Жадные алгоритмы**
>
> «Разделяй и властвуй»: быстрая сортировка, сортировка слиянием, пирамидальная сортировка
>
> Без сравнения: блочная сортировка,
>
> сортировка подсчетом, поразрядная сортировка Стратегия «разделяй и властвуй»
>
> Примеры задач: двоичный поиск, построение дерева, Ханойская башня
>
> Задача поиска с возвратом, каркас кода
>
> Примеры задач: перестановки, сумма подмножеств, n ферзей
>
> Перебор, рекурсия с мемоизацией, восходящая рекурсия
>
> Перекрывающиеся подзадачи, оптимальная подструктура, отсутствие последействия
>
> Методы определения задач динамического программирования, этапы решения
>
> Примеры задач: рюкзак 0-1, полный рюкзак, расстояние редактирования
>
> Характеристики жадных задач, этапы решения
>
> Примеры задач: дробный рюкзак, максимальная вместимость, максимальное произведение разбиения
>
> 0.1. О книге ❖ **13**
2. **Структуры данных**: классификация основных типов данных и структур данных. Определение, преимущества и недостатки, основные операции, распространенные типы, типичные приложения и методы реализации мас- сивов, списков, стеков, очередей, хеш-таблиц, деревьев, куч, графов и т. д.
3. **Алгоритмы**: определение, преимущества и недостатки, эффективность, области применения, этапы решения и примеры задач для поиска, со- ртировки, алгоритма «разделяй и властвуй», обратного поиска, динами- ческого программирования, жадных алгоритмов и т. д.
### Благодарности
> Эта книга постоянно совершенствуется благодаря совместным усилиям множества участников открытого сообщества. Благодарим каждого автора, вложившего свое время и силы. Имена перечислены в порядке, автоматически сгенерированном GitHub: krahets, coderonion, Gonglja, nuomi1, Reanon, justin-tse, hpstory, danielsss, curtishd, night-cruise, S-N-O-R-L-A-X, msk397, gvenusleo, khoaxuantu, RiverTwilight, rongyi, gyt95, zhuoqinyue, K3v123, Zuoxun, mingXta, hello-ikun, FangYuan33, GN-Yu, yuelinxin, longsizhuo, Cathay-Chen, guowei-gong, xBLACKICEx, IsChristina, JoseHu- ng, qualifier1024, QiLOL, pengchzn, Guanngxu, L-Super, WSL0809, Slone123c, lhxsm, yuan0221, what-is-me, theNefelibatas, longranger2, cy-by-side, xiongsp, Jefferson- Huang, Transmigration-zhou, magentaqin, Wonderdch, malone6, xiaomiusa87, gaofer, bluebean-cloud, a16su, Shyam-Chen, nanlei, hongyun-robot, Phoenix0415, MolDuM, Nigh, he-weilai, junminhong, mgisr, iron-irax, yd-j, XiaChuerwu, XC-Zero, seven1240, SamJin98, wodray, reeswell, NI-SW, Horbin-Magician, Enlightenus, xjr7670, YangXu- anyi, DullSword, boloboloda, iStig, qq909244296, jiaxianhua, wenjianmin, keshida, kilikilikid, lclc6, lwbaptx, liuxjerry, lucaswangdev, lyl625760, hts0000, gledfish, fbigm, echo1937, szu17dmy, dshlstarr, Yucao-cy, coderlef, czruby, bongbongbakudan, beinten- tional, ZongYangL, ZhongYuuu, luluxia, xb534, bitsmi, ElaBosak233, baagod, zhouLion, yishangzhang, yi427, yabo083, weibk, wangwang105, th1nk3r-ing, tao363, 4yDX3906, syd168, steventimes, sslmj2020, smilelsb, siqyka, selear, sdshaoda, Xi-Row, popozhu, nuquist19, noobcodemaker, XiaoK29, chadyi, ZhongGuanbin, shanghai-Jerry, JackYang- hellobobo, Javesun99, lipusheng, BlindTerran, ShiMaRing, FreddieLi, FloranceYeh, iF- leey, fanchenggang, gltianwen, goerll, Dr-XYZ, nedchu, curly210102, CuB3y0nd, KraHsu, CarrotDLaw, youshaoXG, bubble9um, fanenr, eagleanurag, LifeGoesOnionOnionOnion, 52coder, foursevenlove, KorsChen, hezhizhen, linzeyan, ZJKung, GaochaoZhu, hopk- ings2008, yang-le, Evilrabbit520, Turing-1024-Lee, thomasq0, Suremotoo, Allen-Scai, Risuntsy, Richard-Zhang1019, qingpeng9802, primexiao, nidhoggfgg, 1ch0, MwumLi, martinx, ZnYang2018, hugtyftg, logan-qiu, psychelzh, Keynman, KeiichiKasai и 0130w. Рецензирование кода книги выполнили coderonion, curtishd, Gonglja, gve- nusleo, hpstory, justin-tse, khoaxuantu, krahets, night-cruise, nuomi1, Reanon и ron- gyi (в алфавитном порядке). Благодарим их за потраченное время и усилия, ко-
торые обеспечили стандартизацию и единообразие кода на различных языках.
> В процессе создания этой книги мне помогало много людей.
1. Благодарю моего наставника в компании, доктора Ли Си (Li Xi), который в одной из бесед вдохновил меня «действовать быстро», что укрепило мою решимость написать эту книгу.
2. Благодарю мою девушку Паo Пао (Pao Pao), которая, будучи первым чи- тателем книги, дала множество ценных советов с точки зрения новичка в алгоритмах, что сделало книгу более понятной и доступной.
3. Благодарю Тен Бао (Teng Bao), Ци Бао (Qi Bao) и Фей Бао (Fei Bao) за креа- тивное название книги, которое навевает приятные воспоминания о на- писании первой строки кода «Hello World!».
4. Благодарю Сяо Цюань (Xiao Quan) за профессиональную помощь в во- просах интеллектуальной собственности, что сыграло важную роль в со- вершенствовании этой открытой книги.
5. Благодарю Су Тун (Su Tong) за дизайн обложки и логотипа книги, а также за терпение при многократных исправлениях по моим просьбам.
6. Благодарю \@squidfunk за советы по оформлению и за разработку от- крытой темы документации Material-for-MkDocs.
> В процессе написания я ознакомился с множеством учебников и статей по структурам данных и алгоритмам. Эти работы послужили отличным образцом для этой книги, обеспечив ее точность и качество. Выражаю благодарность всем преподавателям и предшественникам за их выдающийся вклад!
>
> Настоящая книга пропагандирует метод обучения, сочетающий умственную и практическую деятельность, на который меня вдохновила книга Dive into Deep Learning («Погружение в глубокое обучение», на англ. языке). Настоятель- но рекомендую эту замечательную работу всем читателям.
>
> **Сердечно благодарю своих родителей, ведь именно ваша постоянная поддержка и ободрение дали мне возможность заняться этим увлека- тельным делом.**
#### как использовать эту книгу
### Стиль изложения
- Главы, имеющие символ \* после заголовка, являются дополнительными и содержат более сложный материал. Если у вас ограничено время, мож- но их пропустить.
- Профессиональные термины выделяются полужирным шрифтом (в печат- ной и PDF-версии) или подчеркиванием (в веб-версии), например **массив** (array). Рекомендуется запоминать их для удобства чтения литературы.
- Важные моменты и обобщающие фразы выделяются **полужирным шрифтом**, на такие тексты следует обращать особое внимание.
- При упоминании терминов, различающихся в разных языках програм- мирования, в качестве стандарта используется Python, например None для обозначения «пустого значения».
- В некоторых местах книга отходит от стандартов комментирования про- граммного кода ради более компактного оформления. Комментарии де- лятся на три типа: заголовочные, содержательные и многострочные.
> \"\"\" Заголовочные комментарии, используются для обозначения функций, классов, тестовых примеров и т.д. \"\"\"
>
> \# Содержательные комментарии, используются для пояснения кода.
>
> \"\"\"
>
> Многострочные комментарии. \"\"\"
### Эффективное обучение с помощью анимированных иллюстраций
> Видео и изображения обладают более высокой плотностью информации и структурированностью по сравнению с текстом, что облегчает понимание. В этой книге **ключевые и сложные моменты в основном представлены в виде анимированных иллюстраций**, а текстовая информация служит по- яснением и дополнением.
>
> Если какой-либо раздел в книге сопровождается анимационной иллюстра- цией, как на рис. 0.2, **используйте иллюстрацию в качестве основного ис- точника информации, а текст -- в качестве вспомогательного**.
![](ru/docs/assets/media/image36.jpeg){width="5.06667760279965in" height="3.4239577865266844in"}
> **Рис. 0.2.** Пример анимационной иллюстрации. Шаг 1
>
> ![](ru/docs/assets/media/image37.jpeg){width="5.066665573053369in" height="3.4239577865266844in"}
![](ru/docs/assets/media/image38.jpeg){width="5.066665573053369in" height="3.4239577865266844in"}
> **Рис. 0.2.** *Продолжение*. Шаги 2--3
>
> ![](ru/docs/assets/media/image39.jpeg){width="5.066665573053369in" height="3.4239577865266844in"}
![](ru/docs/assets/media/image40.jpeg){width="5.066674321959755in" height="3.4239577865266844in"}
> **Рис. 0.2.** *Окончание*. Шаги 4--5
### Углубление понимания через практику написания кода
> Сопроводительный код размещен в репозитории GitHub, **он содержит тесто- вые примеры и может быть запущен одним нажатием кнопки**, как по- казано на рис. 0.3.
![](ru/docs/assets/media/image41.jpeg){width="5.0666863517060365in" height="3.4239577865266844in"}
> **Рис. 0.3.** Запуск примера кода
>
> Если позволяет время, **рекомендуется самостоятельно набирать код**. Если время ограничено, по крайней мере **просмотрите и выполните весь код**.
>
> Процесс написания кода приносит больше пользы, чем его чтение. **Настоя- щее обучение -- это обучение на практике**.
>
> Предварительная подготовка для запуска кода включает три этапа.
1. **Установка локальной среды программирования**. Следуйте инструк- циям программы установки. Если среда уже установлена, этот шаг мож- но пропустить.
2. **Клонирование или загрузка репозитория кода**. Перейдите в репози- торий GitHub. Если у вас установлена утилита Git, можно клонировать репозиторий с помощью следующей команды:
> git clone https://github.com/krahets/hello-algo.git
>
> Либо можно нажать кнопку **Download ZIP** (Скачать ZIP-архив), как показа- но на рис. 0.4, загрузить архив с кодом и затем распаковать его на локальном компьютере.
>
> ![](ru/docs/assets/media/image43.jpeg)
>
> **Рис. 0.4.** Клонирование репозитория и загрузка кода
3. **Запуск исходного кода**. Если для блока кода в книге указано имя фай- ла, этот файл можно найти в папке codes репозитория, как показано на рис. 0.5. Исходный код можно запустить одним нажатием, что поможет вам сэкономить время на отладку и сосредоточиться на изучении ма- териала.
![](ru/docs/assets/media/image45.jpeg)
> **Рис. 0.5.** Блоки кода и соответствующие файлы исходного кода
>
> Помимо локального запуска, **в веб-версии книги код на Python можно выполнить в визуальной среде** (реализовано на основе pythontutor). Для этого нажмите кнопку **Визуализировать выполнение** под блоком кода, как показано на рис. 0.6. Также в раскрывшемся окне можно нажать кнопку **От- крыть в полноэкранном режиме** для более удобного просмотра1.
![](ru/docs/assets/media/image46.jpeg){width="5.122829177602799in" height="3.12in"}
> **Рис. 0.6.** Визуальное выполнение кода Python
### Совместное развитие через вопросы и обсуждения
> При чтении книги не оставляйте без внимания непонятные моменты. **Мы при- зываем вас задавать вопросы в разделе комментариев**, и я вместе с колле- гами постараюсь ответить вам в течение двух дней.
>
> В конце каждой главы веб-версии книги предусмотрено место для коммен- тариев, как показано на рис. 0.7. Рекомендуется уделять внимание содержимо- му этой области. С одной стороны, это позволит вам понять, с какими пробле- мами сталкиваются другие читатели, что поможет выявить пробелы в знаниях и стимулировать более глубокое понимание. С другой стороны, мы надеемся, что вы будете отвечать на вопросы других участников и делиться своими мне- ниями.
>
> 1 Функция визуального выполнения кода доступна только в китайской веб-версии книги -- *Прим. перев*.
>
> ![](ru/docs/assets/media/image47.jpeg){width="5.066666666666666in" height="3.4239577865266844in"}
>
> **Рис. 0.7.** Пример раздела комментариев
### Дорожная карта изучения алгоритмов
> Процесс изучения структур данных и алгоритмов можно разделить на три этапа.
1. **Введение в алгоритмы**. Необходимо ознакомиться с особенностями и применением различных структур данных, изучить принципы, про- цессы, назначение и эффективность различных алгоритмов.
2. **Решение алгоритмических задач**. Рекомендуется начинать с популяр- ных задач и решить не менее 100 из них, чтобы познакомиться с основ- ными алгоритмическими проблемами. При первом решении задач вы можете столкнуться с так называемым забвением знаний -- не беспокой- тесь, это нормально. Следуйте при повторении задач кривой забывания Эббингауза, обычно после 3--5 циклов повторения они хорошо запоми- наются. Рекомендуемые списки задач и планы решения можно найти в **этом репозитории GitHub**.
3. **Построение системы знаний**. В процессе обучения можно читать статьи по алгоритмам, изучать типичные решения и учебники по алгоритмам, чтобы постоянно обогащать систему знаний. В решении задач можно при- менять продвинутые стратегии, такие как классификация по темам, множе- ственные решения одной задачи или одно решение для множества задач. Советы по этим техникам обучения можно найти в различных сообществах.
> Эта книга в основном охватывает первый этап и призвана помочь вам эф- фективно подготовиться ко второму и третьему этапам обучения, как показа- но на рис. 0.8.
1. Резюме ❖ **23**
> ![](ru/docs/assets/media/image49.jpeg)*Этап 1*
>
> **Базовые сведения**
>
> *Этап 2*
>
> **Тренировка навыков**
>
> *Этап 3*
>
> **Построение системы знаний**
>
> **Решение алгоритмических задач**
>
> **Периодическое повторение** *Повторное решение одной и той же задачи через определенное время*
>
> *для формирования долговременной памяти и углубления понимания*
>
> **Активное обобщение** *Систематизация содержа*- *ния, выявление законо*-
>
> *мерностей для построения целостной системы знаний*
#### резюме
> **Рис. 0.8.** Дорожная карта изучения алгоритмов
- Основная аудитория книги -- новички в изучении алгоритмов. Если у вас уже есть определенная база, книга поможет систематизировать имею- щиеся знания об алгоритмах, а исходный код послужит инструменталь- ной библиотекой для решения задач.
- Содержание книги включает три основные части -- анализ сложности, структуры данных и алгоритмы -- и охватывает большинство тем в этой области.
- Для новичков в алгоритмах крайне важно изучить начальные разделы книги, чтобы избежать множества ошибок в будущем.
- Анимированные иллюстрации в книге обычно используются для пред- ставления ключевых и сложных аспектов. При чтении книги следует уде- лять этим материалам большое внимание.
- Практика -- лучший способ изучения программирования. Настоятельно рекомендуется запускать исходный код и самостоятельно писать про- граммы.
- В веб-версии книги каждая глава имеет область комментариев, где вы можете задавать вопросы и делиться своим мнением.
> Глава 1