# Введение ![](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