- •Структуры и алгоритмы обработки данных
- •Логическая и физическая структуры данных
- •Классификация структур данных
- •Основные операции над структурами данных
- •Алгоритм и примеры задач, решаемых с помощью алгоритмов
- •Адресация и распределение памяти
- •Адресные пространства и модели оперативной памяти
- •Формирование физического адреса в реальном режиме
- •Особенности адресации в защищенном режиме
- •Кэширование
- •Анализ алгоритмов
- •Быстродействие – основной показатель эффективности алгоритма
- •Подсчет числа простейших операций
- •Лучший, средний и худший случаи
- •Алгоритмы и платформы
- •Виртуализация памяти
- •Использование кэша
- •Выравнивание данных
- •Рандомизированные алгоритмы
- •Общая характеристика записей и способы описания в Delphi
- •Многоуровневые записи
- •Выравнивание и упакованные записи
- •Записи с вариантной частью
- •Массивы
- •Общая характеристика массивов
- •Статические (стандартные) массивы
- •Многомерные статические массивы
- •Свойства статических массивов
- •Открытые массивы
- •Динамические массивы
- •Динамические векторы
- •Многомерные динамические массивы
- •Массивы типа Variant
- •Вставка и удаление в массиве
- •Связные списки и алгоритмы их обработки
- •Списки и их разновидности
- •Односвязный список
- •Общая характеристика односвязного списка
- •Структура элемента односвязного списка
- •Формирование односвязного списка
- •Просмотр односвязного списка
- •Вставка элемента в односвязный список
- •Удаление элемента из односвязного списка
- •Линейный двухсвязный список
- •Структура элемента двухсвязного списка
- •Реализация операций в линейном двухсвязном списке
- •Нелинейный двухсвязный список
- •Нелинейный трехсвязный список
- •Определение плекса и его общие признаки
- •Иерархическая списковая структура. Сетевая структура
- •Достоинства и недостатки связных списков
- •Функциональные и свободные списки
- •Общая характеристика функционального и свободного списка
- •Методы формирования свободного списка
- •Стеки, очереди, деки и операции в них
- •Общая характеристика
- •Очередь
- •Динамические множества и словари
- •Общая характеристика
- •Операции в динамических множествах
- •Деревья
- •Общая характеристика и некоторые определения
- •Представление дерева в памяти
- •Естественное представление дерева
- •Представление дерева с помощью вектора
- •Представление дерева с использованием списков сыновей
- •Методы обхода деревьев
- •Бинарное дерево
- •Структура бинарного дерева
- •Формирование бинарного дерева
- •Обход бинарного дерева
- •Преобразование любого дерева к бинарному дереву
- •Включение и исключение в дереве
- •Включение в дереве
- •Исключение в дереве
- •Поиск: определение и общая терминология
- •Линейный (последовательный) поиск
- •Последовательный поиск в упорядоченной таблице
- •Последовательный поиск при накоплении запросов
- •Индексно-последовательный поиск
- •Бинарный поиск
- •Поиск, использующий бинарное дерево
- •Сортировка
- •Общие сведения и некоторые определения
- •Внутренняя сортировка
- •Сортировка прямыми включениями
- •Сортировка бинарными включениями
- •Сортировка прямым выбором
- •Сортировка прямым обменом
- •Сортировка методом Шелла
- •Сортировка с помощью бинарного дерева
- •Пирамидальная сортировка
- •Быстрая сортировка разделением
- •Внешняя сортировка
- •Сортировка прямым слиянием
- •Сортировка естественным слиянием
- •Сортировка многопутевым слиянием
- •Многофазная сортировка
- •Хеширование и хеш-таблицы
- •Общие сведения и определения
- •Коллизии при хешировании
- •Разрешение коллизий при хешировании
- •Разрешение коллизий методом открытой адресации
- •Разрешение коллизий методом цепочек
- •Функции хеширования
- •Поисковые деревья
- •Бинарное дерево поиска
- •Структура бинарного дерева поиска и алгоритм поиска
- •Вставка элемента в бинарное дерево поиска
- •Удаление из бинарного дерева поиска
- •Красно-черные деревья
- •Определение красно-черного дерева, структура его элементов
- •Повороты
Свойства статических массивов
Статические массивы характеризуются следующими свойствами:
постоянство структуры в течение всего времени ее существования,
смежность элементов и непрерывность области памяти, отводимой сразу для всех элементов структуры.
простота и постоянство отношений между элементами структуры, позволяющие исключить информацию об этих отношениях из области памяти, выделенной для элементов структуры, и хранить ее в компактной форме в дескрипторах.
Открытые массивы
В списке параметров, помещаемом в заголовках функций и процедур, допускается указывать массивы. Если размер воспринимаемого массива фиксирован, то в списке параметров тип такого параметра задается только с помощью идентификатора типа. Подпрограммы Object Pascal могут воспринимать также массивы, размер которых неизвестен. В этом случае в заголовке подпрограммы после записи имени параметра-массива указывается слово array, а затем базовый тип, а описание индексов не приводится. Например,
Procedure InverArray(D: Array Of Real;
Var T: Array Of Real);
Такие массивы (как D и T) называются открытыми массивами.
При таком определении массивов D и T тот массив, который передается в процедуру InverArray первым в качестве фактического параметра, будет копироваться в стек, и с этой копией массивом D будет работать процедура. Второй открытый массив (массив Т) определен как Var. Этот массив передается «по ссылке», т. е. он не копируется в стек, и процедура будет работать с тем массивом, который был передан в качестве фактического параметра при вызове InverArray.
Массив, переданный как открытый, воспринимается в теле процедуры или функции как массив с целыми индексами, начинающимися с нуля. При этом не имеет значения, как был объявлен диапазон для индекса в массиве, переданном в процедуру в виде фактического параметра.
Динамические массивы
Динамические векторы
Динамические массивы относятся к классу динамических структур. Физическое существование динамического массива реализуется в специальной области памяти, называемой куча (heap). Эта область предназначена для динамического распределения.
Динамические массивы отличаются от стандартных статических массивов тем, что в них не объявляется заранее число элементов. Поэтому динамические массивы удобно использовать в приложениях, где объем обрабатываемых массивов заранее неизвестен и определяется в процессе выполнения в зависимости от действий пользователя или объема обрабатываемой информации.
Объявление типа одномерного динамического массива, называемого также динамическим вектором, содержит только имя типа, ключевое слово array и идентификатор типа. Переменная типа «динамический вектор» объявляется обычным образом. Например, динамический вектор dinArr может быть объявлен следующим образом:
Type TdinVector = Array Of Real;
Var dinArr: TdinVector;
Если объявленный в секции Var статический массив размещается компилятором в памяти, то объявление динамического массива не приводит к отведению памяти для него. В памяти лишь резервируется 4‑байтовая ячейка, в которую будет занесен адрес динамически создаваемого участка памяти. Сам участок памяти для динамического массива создается при выполнении процедуры SetLength.
Для создания динамического вектора в функцию SetLength в качестве аргументов передаются имя массива и целая неотрицательная величина, значение которой равно количеству элементов создаваемого массива. Например, результатом вызова
SetLength(dinArr, 10);
будет выделение для вектора dinArr участка памяти под 10 элементов типа Real и задает всем элементам нулевые значения. Индексы динамического массива всегда целые числа, начинающиеся с нуля. Поэтому в приведенном примере вектор состоит из элементов от dinArr[0] до dinArr[9].
Повторное применение SetLength к уже существующему массиву изменяет его размер. Если новое значение размера больше предыдущего, то все предыдущие значения элементов сохраняются, и в конце массива добавляются новые нулевые элементы базового типа. Если же новый размер меньше предыдущего, то массив усекается «справа» и в нем остаются значения начальных элементов. Усечение можно проводить функцией Copy, присваивая ее результат самому массиву, например, вызов
dinArr:= Copy(dinArr, 0, 3);
усекает динамический вектор dinArr, оставляя неизменными первые три его элемента.
Сама переменная динамического массива (в нашем примере это переменная dinArr) является указателем на начало массива. Если место под массив еще не выделено, значение этой переменной равно Nil. Операция сравнения А = В двух динамических массивов даст True только в том случае, если А и В указывают на один и тот же массив. Но это не совсем обычный указатель. Его нельзя, например, разыменовать операцией ^ , нельзя передать в процедуры New и Dispose.
Удалить из памяти динамический массив можно одним из следующих способов:
присвоить ему значение Nil, например, dinArr:= Nil;
использовать функцию Finalize: Finalize(dinArr);
установить функцией SetLength нулевую длину, например,
SetLength(dinArr, 0);
Динамические массивы могут передаваться в подпрограммы в качестве фактических параметров вместо формальных параметров, объявленных как открытые массивы.
Как указывалось выше, физическое существование динамического массива реализуется в специальной области памяти, называемой куча (heap). Эта область предназначена для динамического распределения. Поскольку одномерный динамический массив, как и статический, является последовательной структурой (т. е. участок памяти для массива непрерывен и слоты его элементов смежны), при изменении размеров массива можно наблюдать перемещение участка на новое место в куче. Например, пусть в программе записана следующая последовательность вызовов:
SetLength(D, 3);
SetLength(С, 4);
SetLength(D, 6);
где D и С динамические векторы с одинаковым базовым типом. Тогда в результате выполнения второго вызова SetLength(С, 4) участок памяти для С будет создан сразу после участка вектора D, созданного при первом вызове SetLength(D, 3). Третий вызов должен увеличить участок для размещения нового вектора D. Поскольку новый участок должен превосходить старый вдвое, то «старых» ячеек ему будет недостаточно. Поэтому третий вызов приведет к появлению нового участка, содержащего смежные слоты элементов вектора D, и этот участок будет расположен после участка отведенного ранее для вектора С.