"Информатика", Поляков К.Ю., Еремин Е.А.
Связанный список и дерево — способы организовать данные с помощью узлов и связей между ними. В списке элементы выстроены в цепочку, а в дереве связи образуют уровни и ветви. Такие структуры помогают описывать последовательности, папки и другие отношения между объектами. Чтобы работать с ними, нужно понимать, какие ссылки хранят узлы, где находится начало структуры и как переходить от одного элемента к другому.
Текст подготовлен нейронной сетью по теме параграфа и не заменяет учебник — важные факты и формулировки сверяйте с ним.
Список — упорядоченная последовательность элементов, порядок которой задают связи между ними. В связанном списке порядок не обязательно совпадает с расположением элементов в памяти. Это позволяет соединять данные ссылками и менять состав последовательности.
Элемент списка — часть структуры, в которой хранятся данные и ссылка на следующий элемент. В двусвязном списке есть также ссылка на предыдущий элемент. Такие ссылки позволяют определить соседей элемента и направление перехода по списку.
Дерево — структура из связанных узлов без циклов: если двигаться по связям, нельзя вернуться в исходный узел. Один узел является корнем, остальные располагаются ниже по уровням. Это определение помогает отличить дерево от произвольной сети связей.
Узел дерева — отдельный элемент структуры. Связанный с ним узел выше называется родителем, а узлы ниже — детьми; узел без детей называют листом. Поддерево — это выбранный узел вместе со всеми его потомками, то есть узлами, находящимися ниже него.
Чтобы получить связанный список из отдельных элементов, в каждом элементе сохраняют ссылку на следующий. Начало списка указывает на первый элемент, а ссылка последнего обычно не ведёт к другому элементу. Поэтому для поиска нужно идти от начала и переходить по очередной ссылке: отдельный элемент может не иметь известного адреса или номера, по которому к нему можно обратиться сразу.
В односвязном списке элемент хранит ссылку только на следующий элемент. По цепочке можно двигаться вперёд, но чтобы вернуться назад, придётся начинать сначала. В двусвязном списке есть ссылка и на предыдущий элемент, поэтому можно перемещаться в обе стороны; за эту возможность приходится хранить дополнительную ссылку.
У дерева есть корень, от которого начинается движение по структуре. Связи от родителя к детям образуют ветви, а узлы располагаются на уровнях: корень находится выше своих детей, те могут иметь собственных детей. У каждого узла, кроме корня, один родитель, потому что иначе связи могли бы соединить разные ветви в сеть, а не в дерево. Узлы без детей становятся листьями.
Дерево удобно, если данные естественно делятся на группы и подгруппы. Например, главная папка может быть корнем, вложенные папки — дочерними узлами, а файлы — узлами на нижних уровнях. Похожим образом можно представить понятие и его более частные разновидности: движение вниз по ветвям показывает, к какой группе относится каждый объект.
Список и дерево различаются тем, какие отношения они показывают. В списке у элемента обычно есть предшественник и следующий элемент, поэтому структура образует цепочку. В дереве у узла может быть несколько детей, и от него расходятся ветви; такая форма описывает иерархию, но не один общий линейный порядок всех узлов.
| Признак | Список | Дерево |
|---|---|---|
| Как устроены связи между элементами | Элементы соединены в цепочку | Узлы связаны по уровням и ветвям |
| Как определяется начало структуры | Указывается первый элемент списка | Указывается корень |
| Какие элементы имеют соседей или потомков | Элементы имеют ссылки на соседей | У узла могут быть дети и потомки |
| Можно ли представить разветвление | Нет, порядок линейный | Да, от узла могут отходить ветви |
| Пример применения | Последовательность задач | Папки и файлы |
Сначала определите, нужно ли описать цепочку или иерархию: это главный признак выбора структуры. Затем сравните, как обозначается начало и какие связи есть у элементов. Например, для порядка выполнения задач подходит список, а для вложенности папок — дерево.
Условие. Для последовательности из пяти элементов нужно определить, какие ссылки задать, чтобы получить односвязный список. Обозначим элементы A, B, C, D и E в требуемом порядке. В односвязном списке у каждого элемента есть ссылка на следующий, поэтому важно сохранить последовательность и отметить её начало.
Ответ. Начало списка указывает на A; ссылки имеют вид A → B → C → D → E, а ссылка из E на следующий элемент пустая. Так каждый элемент, кроме последнего, ведёт к следующему.
Условие. По схеме дерева нужно определить корень, листья, родителей и детей заданного узла. Пусть на верхнем уровне находится R, под ним — A и B, а под A расположены C и D; у B детей нет. Нужно читать схему от верхнего узла вниз, не путать непосредственных детей с более далёкими потомками.
Ответ. Корень — R, дети R — A и B, дети A — C и D, а листья — B, C и D. Например, B — лист, хотя он не находится на самом нижнем уровне схемы отдельно от остальных: решает отсутствие детей.
Условие. Представьте папку «Проекты», в которой есть папки «Информатика» и «Фото». В папке «Информатика» лежит папка «Сайт», а в ней — файл «главная.html». Требуется изобразить структуру деревом и указать путь к файлу. Папки и файл рассматриваются как узлы, а вложенность задаёт связь родителя и ребёнка.
Ответ. Структура имеет вид: «Проекты» → «Информатика» → «Сайт» → «главная.html», а папка «Фото» — другая ветвь от корня. Путь к файлу проходит через эти четыре узла, поскольку каждый следующий вложен в предыдущий.
Называть списком любую последовательность значений — значит забывать, что в связанной структуре порядок задаётся ссылками. Ошибка возникает потому, что привычный ряд чисел тоже выглядит упорядоченным. Проверьте себя: можете ли вы показать, какая ссылка ведёт от одного элемента к следующему?
Считать, что к элементу связанного списка можно обратиться по номеру так же быстро, как в массиве, неверно. В массиве элементы доступны по позиции, а в списке часто нужно пройти цепочку от начала. Если для поиска вы перескакиваете сразу к нужному номеру, проверьте, предусмотрен ли такой прямой доступ.
Путать корень и лист нельзя: корень не имеет родителя, а лист не имеет дочерних узлов. Ошибка появляется, когда «верхний» и «нижний» понимают только по расположению на рисунке. Проверяйте связи: у корня нет родителя, у листа — детей.
Считать, что у узла дерева может быть несколько родителей, — значит смешивать дерево с сетью связей. Такое впечатление может возникнуть, если потомка принимают за непосредственного ребёнка или смотрят на схему невнимательно. Для проверки проследите связи вверх: у любого узла, кроме корня, должен быть ровно один родитель.
Для работы с этими структурами пригодятся понятия последовательности, элемента данных и ссылки на объект. Списки используют при изучении структур данных и алгоритмов обработки последовательностей: например, когда нужно переходить по элементам в заданном порядке. Деревья встречаются в файловых системах, при описании иерархических данных и при изучении способов поиска информации, где разветвление помогает группировать объекты.
Чем связанный список отличается от обычной последовательности?
Обычная последовательность задаёт порядок значений, а связанный список хранит его с помощью ссылок между элементами. Поэтому для работы со списком важно знать не только сами данные, но и связи.
Почему к элементу связанного списка нельзя обратиться напрямую по его номеру?
Элементы списка не обязаны располагаться рядом в памяти и обычно не имеют общего способа прямого доступа по номеру. Чтобы найти нужный элемент, переходят по ссылкам от начала списка, считая шаги.
Может ли у дерева быть несколько корней?
У обычного дерева один корень — узел, с которого начинается структура. Если независимых корней несколько, это уже несколько деревьев, то есть лес.
Как отличить лист дерева от обычного узла?
У листа нет дочерних узлов, поэтому от него не отходят ветви вниз. У обычного узла может быть один или несколько детей.
В каких задачах удобнее использовать дерево, а не список?
Дерево удобно, когда данные образуют уровни и ветви: например, в структуре папок или классификации понятий. Список подходит для данных, которые нужно расположить в одну цепочку.
§ 16. Списки и деревья