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

29 KiB
Raw Blame History

Введение

{width="4.60417760279965in" height="5.958333333333333in"}

  1. О книге

Этот проект задуман как открытое, бесплатное и дружелюбное к новичкам введение в структуры данных и алгоритмы.

  1. В книге используются анимационные иллюстрации. Материал изложен ясно и последовательно, что облегчает освоение и помогает начинаю- щим построить «карту знаний» по структурам данных и алгоритмам.

  2. Исходный код можно запустить одним кликом, что позволяет трениро- ваться, развивать навыки программирования и формировать понима- ние принципов работы алгоритмов и реализации структур данных на фундаментальном уровне.

  3. Мы призываем к взаимопомощи читателей: задавайте вопросы и дели- тесь идеями в комментариях. Обсуждения помогают двигаться вперед всем вместе.

Целевая аудитория

Если вы новичок в алгоритмах, никогда с ними не сталкивались или у вас есть некоторый опыт решения задач, но еще нет четкого понимания структур дан- ных и алгоритмов, эта книга создана специально для вас!

Если у вас уже есть определенный опыт решения задач и вы знакомы с боль- шинством типов задач, эта книга поможет вам освежить и систематизировать знания об алгоритмах. Исходный код может служить набором инструментов для решения задач или алгоритмическим словарем.

Если вы владеете алгоритмами на экспертном уровне, мы будем рады ва- шим ценным советам или совместному участию в создании книги.

Структура книги

Основное содержание книги представлено на рис. 0.1.

  1. Анализ сложности: критерии и методы оценки структур данных и ал- горитмов. Методы расчета временной и пространственной сложности, распространенные типы, примеры и т. д.

Структуры данных

Структуры данных

Массивы и списки

Стек

[и]{.smallcaps} очередь

Хеш- таблицы

Логическая и физическая структура Базовые типы данных

Цифровое и символьное кодирование

Способы непрерывного и распределенного хранения Методы работы, преимущества

[и]{.smallcaps} недостатки двух способов

Реализация списка на основе динамического массива

Память и кеш в компьютере

Последний пришел -- первый вышел, первый пришел -- первый вышел, двусторонняя очередь

Реализация на основе массива и связного списка

Принцип работы хеш-таблицы, реализация на основе массива

Хеш-коллизии, цепная и открытая адресация Назначение и цели хеш-алгоритмов

Идеальное, совершенное, полное, сбалансированное

двоичное дерево

Анализ сложности

Итерация и рекурсия

Временная сложность

Пространственная сложность

Поиск

Циклы for и while, вложенные циклы

Стек вызовов рекурсии, хвостовая рекурсия, дерево рекурсии

Сравнение итерации и рекурсии

Асимптотическая верхняя граница

Методы вычисления, основные типы

Наихудшая, наилучшая, средняя временная сложность

Методы вычисления, основные типы Компромисс между временем

и пространством

Перебор: линейный поиск, поиск в ширину и глубину

Адаптивный поиск: двоичный поиск, хеш-поиск, поиск по дереву

Выбор алгоритма поиска

Местность, устойчивость, адаптивность, основанность на сравнении

Перебор: сортировка выбором, пузырьком, вставками

Деревья

Куча

Графы

https://github.com/krahets/hello-algo

Представление связным списком и массивом, сравнение Обход в ширину; прямой, симметричный и обратный порядок Двоичное дерево поиска

АВЛ-дерево

Минимальная и максимальная куча, Алгоритмы

очередь с приоритетом

Реализация кучи на основе массива, операция построения кучи

Задача о k наибольших элементов

Ориентированный, связный и взвешенный графы Список и матрица смежности, их сравнение Обход в ширину и в глубину

Сортировка

Разделяй и властвуй

Поиск

с возвратом

Динамическое программирование

Жадные алгоритмы

«Разделяй и властвуй»: быстрая сортировка, сортировка слиянием, пирамидальная сортировка

Без сравнения: блочная сортировка,

сортировка подсчетом, поразрядная сортировка Стратегия «разделяй и властвуй»

Примеры задач: двоичный поиск, построение дерева, Ханойская башня

Задача поиска с возвратом, каркас кода

Примеры задач: перестановки, сумма подмножеств, n ферзей

Перебор, рекурсия с мемоизацией, восходящая рекурсия

Перекрывающиеся подзадачи, оптимальная подструктура, отсутствие последействия

Методы определения задач динамического программирования, этапы решения

Примеры задач: рюкзак 0-1, полный рюкзак, расстояние редактирования

Характеристики жадных задач, этапы решения

Примеры задач: дробный рюкзак, максимальная вместимость, максимальное произведение разбиения

0.1. О книге ❖ 13

  1. Структуры данных: классификация основных типов данных и структур данных. Определение, преимущества и недостатки, основные операции, распространенные типы, типичные приложения и методы реализации мас- сивов, списков, стеков, очередей, хеш-таблиц, деревьев, куч, графов и т. д.

  2. Алгоритмы: определение, преимущества и недостатки, эффективность, области применения, этапы решения и примеры задач для поиска, со- ртировки, алгоритма «разделяй и властвуй», обратного поиска, динами- ческого программирования, жадных алгоритмов и т. д.

Благодарности

Эта книга постоянно совершенствуется благодаря совместным усилиям множества участников открытого сообщества. Благодарим каждого автора, вложившего свое время и силы. Имена перечислены в порядке, автоматически сгенерированном 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, используйте иллюстрацию в качестве основного ис- точника информации, а текст -- в качестве вспомогательного.

{width="5.06667760279965in" height="3.4239577865266844in"}

Рис. 0.2. Пример анимационной иллюстрации. Шаг 1

{width="5.066665573053369in" height="3.4239577865266844in"}

{width="5.066665573053369in" height="3.4239577865266844in"}

Рис. 0.2. Продолжение. Шаги 2--3

{width="5.066665573053369in" height="3.4239577865266844in"}

{width="5.066674321959755in" height="3.4239577865266844in"}

Рис. 0.2. Окончание. Шаги 4--5

Углубление понимания через практику написания кода

Сопроводительный код размещен в репозитории GitHub, он содержит тесто- вые примеры и может быть запущен одним нажатием кнопки, как по- казано на рис. 0.3.

{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, загрузить архив с кодом и затем распаковать его на локальном компьютере.

Рис. 0.4. Клонирование репозитория и загрузка кода

  1. Запуск исходного кода. Если для блока кода в книге указано имя фай- ла, этот файл можно найти в папке codes репозитория, как показано на рис. 0.5. Исходный код можно запустить одним нажатием, что поможет вам сэкономить время на отладку и сосредоточиться на изучении ма- териала.

Рис. 0.5. Блоки кода и соответствующие файлы исходного кода

Помимо локального запуска, в веб-версии книги код на Python можно выполнить в визуальной среде (реализовано на основе pythontutor). Для этого нажмите кнопку Визуализировать выполнение под блоком кода, как показано на рис. 0.6. Также в раскрывшемся окне можно нажать кнопку От- крыть в полноэкранном режиме для более удобного просмотра1.

{width="5.122829177602799in" height="3.12in"}

Рис. 0.6. Визуальное выполнение кода Python

Совместное развитие через вопросы и обсуждения

При чтении книги не оставляйте без внимания непонятные моменты. Мы при- зываем вас задавать вопросы в разделе комментариев, и я вместе с колле- гами постараюсь ответить вам в течение двух дней.

В конце каждой главы веб-версии книги предусмотрено место для коммен- тариев, как показано на рис. 0.7. Рекомендуется уделять внимание содержимо- му этой области. С одной стороны, это позволит вам понять, с какими пробле- мами сталкиваются другие читатели, что поможет выявить пробелы в знаниях и стимулировать более глубокое понимание. С другой стороны, мы надеемся, что вы будете отвечать на вопросы других участников и делиться своими мне- ниями.

1 Функция визуального выполнения кода доступна только в китайской веб-версии книги -- Прим. перев.

{width="5.066666666666666in" height="3.4239577865266844in"}

Рис. 0.7. Пример раздела комментариев

Дорожная карта изучения алгоритмов

Процесс изучения структур данных и алгоритмов можно разделить на три этапа.

  1. Введение в алгоритмы. Необходимо ознакомиться с особенностями и применением различных структур данных, изучить принципы, про- цессы, назначение и эффективность различных алгоритмов.

  2. Решение алгоритмических задач. Рекомендуется начинать с популяр- ных задач и решить не менее 100 из них, чтобы познакомиться с основ- ными алгоритмическими проблемами. При первом решении задач вы можете столкнуться с так называемым забвением знаний -- не беспокой- тесь, это нормально. Следуйте при повторении задач кривой забывания Эббингауза, обычно после 3--5 циклов повторения они хорошо запоми- наются. Рекомендуемые списки задач и планы решения можно найти в этом репозитории GitHub.

  3. Построение системы знаний. В процессе обучения можно читать статьи по алгоритмам, изучать типичные решения и учебники по алгоритмам, чтобы постоянно обогащать систему знаний. В решении задач можно при- менять продвинутые стратегии, такие как классификация по темам, множе- ственные решения одной задачи или одно решение для множества задач. Советы по этим техникам обучения можно найти в различных сообществах.

Эта книга в основном охватывает первый этап и призвана помочь вам эф- фективно подготовиться ко второму и третьему этапам обучения, как показа- но на рис. 0.8.

  1. Резюме ❖ 23

Этап 1

Базовые сведения

Этап 2

Тренировка навыков

Этап 3

Построение системы знаний

Решение алгоритмических задач

Периодическое повторение Повторное решение одной и той же задачи через определенное время

для формирования долговременной памяти и углубления понимания

Активное обобщение Систематизация содержа- ния, выявление законо-

мерностей для построения целостной системы знаний

резюме

Рис. 0.8. Дорожная карта изучения алгоритмов

  • Основная аудитория книги -- новички в изучении алгоритмов. Если у вас уже есть определенная база, книга поможет систематизировать имею- щиеся знания об алгоритмах, а исходный код послужит инструменталь- ной библиотекой для решения задач.

  • Содержание книги включает три основные части -- анализ сложности, структуры данных и алгоритмы -- и охватывает большинство тем в этой области.

  • Для новичков в алгоритмах крайне важно изучить начальные разделы книги, чтобы избежать множества ошибок в будущем.

  • Анимированные иллюстрации в книге обычно используются для пред- ставления ключевых и сложных аспектов. При чтении книги следует уде- лять этим материалам большое внимание.

  • Практика -- лучший способ изучения программирования. Настоятельно рекомендуется запускать исходный код и самостоятельно писать про- граммы.

  • В веб-версии книги каждая глава имеет область комментариев, где вы можете задавать вопросы и делиться своим мнением.

Глава 1