Введение

Абстрактный тип данных, используемый в информатике.
Последовательные структуры данных.
В информатике список или последовательность — это абстрактный тип данных, представляющий собой конечное число упорядоченных значений, где одно и то же значение может встречаться несколько раз. Экземпляр списка является компьютерной реализацией математической концепции кортежа или конечной последовательности; (потенциально) бесконечным аналогом списка является поток. Списки являются базовым примером контейнеров, поскольку содержат другие значения. Если одно и то же значение встречается несколько раз, каждое вхождение считается отдельным элементом. Термин "список" также используется для обозначения нескольких конкретных структур данных, которые могут быть использованы для реализации абстрактных списков, в частности связных списков и массивов. В некоторых контекстах, например, в программировании на Lisp, термин "список" может относиться конкретно к связному списку, а не к массиву. В объектно-ориентированном программировании списки обычно предоставляются как экземпляры подклассов обобщенного класса "список" и перебираются с помощью отдельных итераторов. Многие языки программирования поддерживают типы данных списков и имеют специальный синтаксис и семантику для списков и операций над ними. Список часто можно создать, перечислив элементы в последовательности, разделенные запятыми, точками с запятой и/или пробелами, внутри пары ограничителей, таких как круглые скобки '()', квадратные скобки '[]', фигурные скобки '{}' или угловые скобки '<>'. Некоторые языки могут позволять индексировать или нарезать типы списков, как типы массивов, в этом случае тип данных точнее описывается как массив. В теории типов и функциональном программировании абстрактные списки обычно определяются индуктивно двумя операциями: nil, возвращающей пустой список, и cons, добавляющей элемент в начало списка.

Реализация

Списки обычно реализуются как связанные списки (одиночно или двойно связанные) или как массивы, как правило, переменной длины или динамические массивы. Стандартный способ реализации списков, зародившийся в языке программирования Lisp, заключается в том, что каждый элемент списка содержит как своё значение, так и указатель на местоположение следующего элемента в списке. Это приводит к образованию либо связанного списка, либо дерева, в зависимости от наличия вложенных подсписков. Некоторые старые реализации Lisp (например, реализация Lisp для Symbolics 3600) также поддерживали "сжатые списки" (с использованием CDR-кодирования), которые имели специальное внутреннее представление (невидимое для пользователя). Списки можно обрабатывать с помощью итерации или рекурсии. Первая часто предпочтительнее в императивных языках программирования, в то время как вторая является нормой в функциональных языках. Списки могут быть реализованы как самобалансирующиеся двоичные деревья поиска, хранящие пары индекс-значение, обеспечивающие доступ ко любому элементу за одинаковое время (например, все элементы находятся на листьях, а внутренние узлы хранят индекс самого правого потомка, используемый для направления поиска). Время выполнения операций при этом логарифмически зависит от размера списка, но пока список не изменяется существенно, это создаёт иллюзию произвольного доступа и позволяет выполнять операции обмена, добавления в начало и добавления в конец за логарифмическое время.

Поддержка языков программирования

Некоторые языки программирования не имеют структуры данных "список", но предлагают использовать ассоциативные массивы или таблицы для эмуляции списков. Например, в Lua используются таблицы. Хотя Lua хранит списки с числовыми индексами как массивы внутри, они всё равно воспринимаются как словари. В Lisp списки являются фундаментальным типом данных и могут представлять как программный код, так и данные. В большинстве диалектов список первых трех простых чисел можно записать как (list 2 3 5). В нескольких диалектах Lisp, включая Scheme, список представляет собой коллекцию пар, состоящих из значения и указателя на следующую пару (или значения null), образуя односвязный список.

Приложения

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