Со структурой можно работать: добавлять данные, извлекать их и обрабатывать, например изменять, анализировать, сортировать. Для каждой структуры данных — свои алгоритмы. Работа программиста — правильно выбирать уже написанные готовые либо писать свои.
Главное свойство структур данных в том, что у любой единицы данных должно быть чёткое место, по которому её можно найти. Как определяется это место и как происходит поиск, зависит от конкретной структуры.
Характеристики структур данных следующие:
● Данные в памяти представлены определённым образом, который однозначно позволяет определить структуру.
● Чаще всего внутрь структуры можно добавить элемент или извлечь оттуда. Это свойство не постоянное — бывают структуры, которые нельзя изменять после создания.
● Существуют алгоритмы, которые позволяют взаимодействовать с этой структурой.
При этом данных необязательно должно быть много. Массив из одного элемента — уже структура данных.
Фактически использование структур данных в программировании начинается ещё с задания переменной. Формат переменной — определённая структура данных, так как в память переменная записывается конкретным способом. Но на практике программисты работают с другими структурами, которые объединяют в себе разные переменные и типы данных. Далее приведем описание и классификацию основных структур данных, чтобы было удобнее в них разобраться.
Для простоты восприятия можно считать, что массив — это таблица. Каждый его элемент имеет индекс — «адрес», по которому этот элемент можно извлечь. В большинстве языков программирования индексы начинаются с нуля. То есть первый элемент массива имеет индекс не [1], а [0]. Данные в массиве можно просматривать, сортировать и изменять с помощью специальных операций.
Массивы бывают двух видов:
● Одномерные
У каждого элемента только один индекс. Можно представить это как строку с данными, где одного номера достаточно, чтобы чётко определить положение каждой переменной.
● Многомерные
У каждого элемента два или больше индексов. По сути, это комбинация из нескольких одномерных массивов, то есть вложенная структура.
Основное отличие между одномерным и многомерным массивом ― их размерность и способ организации данных. Одномерный массив ― простая линейная структура данных, многомерный ― более сложная структура данных с несколькими измерениями
● В качестве блоков для более сложных структур данных. Массивы предусмотрены в синтаксисе большинства языков программирования, и на их основе удобно строить другие структуры.
● Для хранения несложных данных небольших объёмов.
● Для сортировки данных.
Элементы в динамический массив можно добавлять без ограничений и куда угодно. Однако, если добавлять их в середину, остальные придётся сдвигать, что занимает много времени. Поэтому лучше всего динамический массив работает при добавлении элементов в конце.
Как применяют динамические массивы:
● В качестве блоков для структур данных.
● Для хранения неопределённого количества элементов.
● Данные.
● Указатель или ссылка на следующий узел.
● В некоторых списках — ещё и ссылка на предыдущий узел.
В итоге получается список, у которого есть чёткая последовательность элементов. При этом сами элементы более разрозненны, чем в массиве, поскольку хранятся отдельно. Быстро перемещаться между элементами списка помогают указатели.
● Для построения более сложных структур данных.
● Для реализации файловых систем.
● Для формирования хэш-таблиц.
● Для выделения памяти в динамических структурах данных.
● Для реализации рекурсии.
● Для вычислений постфиксных значений.
● Для временного хранения данных, например истории запросов или изменений.
Как применяют очереди:
● Для реализации очередей, например на доступ к определённому ресурсу.
● Для управления потоками в многопоточных средах.
● Для генерации значений.
● Для создания буферов.
● Для поддержания множества уникальных элементов.
● Для хранения данных, которые не нужно сортировать.
● Для сравнения, объединения наборов данных и других операций с ними.
● Для быстрого поиска данных.
● Для создания баз, в которых нужно хранить уникальное соответствие между двумя множествами значений. Их помещают в ключ, и структура проверяет, чтобы ключ не повторялся.
Частный случай map — это hash-map, или хэш-таблица. В ней есть ключи и значения, а для их реализации добавляются индексы. Специальная хэш-функция позволяет по ключу вычислить индекс, чтобы найти нужные данные.
Если знать ключ, с помощью хэш-функции можно вычислить индекс и найти данные
В структуре дерева данные хранятся в узлах
● У каждого узла не больше двух дочерних.
● Если новое значение меньше, оно становится левым дочерним либо дочерним левого дочернего.
● Если значение больше, оно становится правым дочерним или дочерним правого дочернего.
Как применяют двоичные деревья:
● Для быстрого поиска данных.
● Для хранения данных в отсортированном виде с возможностью быстро их добавлять и удалять.
Как применяют префиксные деревья:
● Для хранения данных, которые нужно выдавать по цепочке. Например, слова для функции автозаполнения в телефоне: в зависимости от одной набранной буквы дерево выдаёт следующие.
● Для хранения данных, у которых есть повторяющиеся участки. Например IP-адресов.
● В графе возможны циклы, то есть «ребёнок» может быть «родителем» для того же элемента.
● Рёбра тоже могут нести смысловую нагрузку, то есть нужно сохранять их значения.
Графы бывают ориентированные и неориентированные. У первых рёбра между узлами имеют направление, так что порядок элементов важен. У вторых направлений нет, и элементы можно читать и обходить в любом порядке.
У ориентированных графов важен порядок элементов, у неориентированных ― элементы можно менять местами
Здесь каждая строка или столбец — узел. 1 в ячейке означает, что между узлами есть связь, 0 — что связи нет. Если у связей, то есть рёбер графа, есть вес, он как раз может быть помещён в ячейку
● Для хранения информации, связанной друг с другом сложными соотношениями.
● Для анализа соотносящейся друг с другом информации.
● Для построения маршрута из точки А в точку Б.
Структуру данных для работы выбирают в зависимости от задачи. Если нужно что-то простое, подойдёт обычный массив. Когда требуется создать очередь или историю запросов, выбирают связный список или очередь. Если нужен поиск и сортировка, поможет двоичное дерево. Именно поэтому важно знать все типы данных в программировании, чтобы подбирать оптимальный в любой ситуации.
Читать также: