- •Структуры и алгоритмы обработки данных
- •Логическая и физическая структуры данных
- •Классификация структур данных
- •Основные операции над структурами данных
- •Алгоритм и примеры задач, решаемых с помощью алгоритмов
- •Адресация и распределение памяти
- •Адресные пространства и модели оперативной памяти
- •Формирование физического адреса в реальном режиме
- •Особенности адресации в защищенном режиме
- •Кэширование
- •Анализ алгоритмов
- •Быстродействие – основной показатель эффективности алгоритма
- •Подсчет числа простейших операций
- •Лучший, средний и худший случаи
- •Алгоритмы и платформы
- •Виртуализация памяти
- •Использование кэша
- •Выравнивание данных
- •Рандомизированные алгоритмы
- •Общая характеристика записей и способы описания в Delphi
- •Многоуровневые записи
- •Выравнивание и упакованные записи
- •Записи с вариантной частью
- •Массивы
- •Общая характеристика массивов
- •Статические (стандартные) массивы
- •Многомерные статические массивы
- •Свойства статических массивов
- •Открытые массивы
- •Динамические массивы
- •Динамические векторы
- •Многомерные динамические массивы
- •Массивы типа Variant
- •Вставка и удаление в массиве
- •Связные списки и алгоритмы их обработки
- •Списки и их разновидности
- •Односвязный список
- •Общая характеристика односвязного списка
- •Структура элемента односвязного списка
- •Формирование односвязного списка
- •Просмотр односвязного списка
- •Вставка элемента в односвязный список
- •Удаление элемента из односвязного списка
- •Линейный двухсвязный список
- •Структура элемента двухсвязного списка
- •Реализация операций в линейном двухсвязном списке
- •Нелинейный двухсвязный список
- •Нелинейный трехсвязный список
- •Определение плекса и его общие признаки
- •Иерархическая списковая структура. Сетевая структура
- •Достоинства и недостатки связных списков
- •Функциональные и свободные списки
- •Общая характеристика функционального и свободного списка
- •Методы формирования свободного списка
- •Стеки, очереди, деки и операции в них
- •Общая характеристика
- •Очередь
- •Динамические множества и словари
- •Общая характеристика
- •Операции в динамических множествах
- •Деревья
- •Общая характеристика и некоторые определения
- •Представление дерева в памяти
- •Естественное представление дерева
- •Представление дерева с помощью вектора
- •Представление дерева с использованием списков сыновей
- •Методы обхода деревьев
- •Бинарное дерево
- •Структура бинарного дерева
- •Формирование бинарного дерева
- •Обход бинарного дерева
- •Преобразование любого дерева к бинарному дереву
- •Включение и исключение в дереве
- •Включение в дереве
- •Исключение в дереве
- •Поиск: определение и общая терминология
- •Линейный (последовательный) поиск
- •Последовательный поиск в упорядоченной таблице
- •Последовательный поиск при накоплении запросов
- •Индексно-последовательный поиск
- •Бинарный поиск
- •Поиск, использующий бинарное дерево
- •Сортировка
- •Общие сведения и некоторые определения
- •Внутренняя сортировка
- •Сортировка прямыми включениями
- •Сортировка бинарными включениями
- •Сортировка прямым выбором
- •Сортировка прямым обменом
- •Сортировка методом Шелла
- •Сортировка с помощью бинарного дерева
- •Пирамидальная сортировка
- •Быстрая сортировка разделением
- •Внешняя сортировка
- •Сортировка прямым слиянием
- •Сортировка естественным слиянием
- •Сортировка многопутевым слиянием
- •Многофазная сортировка
- •Хеширование и хеш-таблицы
- •Общие сведения и определения
- •Коллизии при хешировании
- •Разрешение коллизий при хешировании
- •Разрешение коллизий методом открытой адресации
- •Разрешение коллизий методом цепочек
- •Функции хеширования
- •Поисковые деревья
- •Бинарное дерево поиска
- •Структура бинарного дерева поиска и алгоритм поиска
- •Вставка элемента в бинарное дерево поиска
- •Удаление из бинарного дерева поиска
- •Красно-черные деревья
- •Определение красно-черного дерева, структура его элементов
- •Повороты
Массивы
Общая характеристика массивов
Массив (array) это структура данных. В Delphi имеется много типов массивов, и каждый такой тип имеет свои специфические особенности. Общим признаком массивов всех типов является возможность прямого доступа к их элементам со стороны программы. Эта возможность обеспечивается нумерацией элементов с помощью числового индекса, который обычно имеет целый тип. Delphi допускает использование в качестве индекса величины как диапазонного, так и перечислимого типов.
Для логического определения массива ему необходимо присвоить имя, указать пару граничных значений индекса (или несколько пар граничных значений индексов), а также указать тип элементов. Все элементы массива имеют одинаковый тип, этот тип называется базовым типом массива. Пара граничных значений индекса задает диапазон изменения значений этого индекса.
Если в объявлении массива определен один диапазон для индекса, то для доступа к любому элементу массива следует указать один единственный индекс, например, Vect[2], где Vect имя массива, объявленное в секции переменных. Такие массивы называются векторами или одномерными массивами. В случае, когда для доступа к некоторому элементу необходимо указать два или более индексов, то такой массив называют многомерным массивом (двумерный, трехмерный и т. д.). Двумерный массив часто называют матрицей, доступ к ее элементу обеспечивается записью двух индексов, например, Matr[k,j]. Количество индексов, которые необходимо указать при использовании отдельного элемента многомерного массива называется размерностью этого массива.
В общем случае границы диапазона индекса могут быть любыми целыми значениями, в том числе и отрицательными; важно чтобы значение левой границы не превышало значения правой границы. На этот счет имеется рекомендация: если нет веских причин делать по-другому, то индексацию следует начинать с нуля (т. е. установить минимальное значение индекса 0). Эта рекомендация обоснована следующими аргументами:
для основных типов массивов, в которых элементы располагаются в памяти непрерывно, в случае индексации от нуля проще вычисляется адрес любого элемента массива;
в описаниях некоторых массивов (динамические и открытые массивы) не допускается указывать граничные значения индекса или индексов; в таких массивах индексация элементов начинается с нуля;
поскольку в языках Си, Си++ и Java индексация всех массивов начинается с нуля, а операционные системы Windows и Linux реализованы на Си или Си++, при вызове API-функций считается, что индекс первого элемента массива равен 0;
в Delphi-библиотеках VCL (библиотека визуальных компонентов) и CLX (кросс-платформенная библиотека компонентов) предполагается, что начальный элемент массива имеет индекс 0.
Статические (стандартные) массивы
Вектор
Объявление вектора или одномерного массива имеет следующий общий вид (здесь и в дальнейшем используем рекомендацию, в соответствии с которой структурированный пользовательский тип объявляется отдельно от объявления переменной этого типа):
Type
<имя типа> = Array [<ограниченный тип>] Of <тип элементов>;
Var <имя массива> : <имя типа>;
Например:
Type
TarrVect = Array [-2..10] Of Integer;
TarrStudent = Array [0..100] Of TStudent;
TStroka = Array [0..10] Of Char;
Var A, B: TarrVect;
arrStudent: TarrStudent;
S: TStroka;
Здесь объявлены два одинаковых массива A и B, все элементы которого имеют тип Integer, и один массив arrStudent, с базовым типом TarrStudent, объявленным в подразделе 5.2. Количество элементов в каждом массиве A и B равно 13, массив arrStudent содержит 101 элемент. Массив символов S это фактически строка, с ним можно обращаться как со строкой.
В рассмотренных примерах индексы были заданы ограниченным целым типом. Так чаще всего и бывает, но это не обязательно. Для индексации массива могут использоваться любые ограниченные или перечислимые типы. Можно определить массив arrColor следующим образом:
Type
Color = (Red, Green, Blue);
Var arrColor: Array [Color] Of Real;
Теперь можно обратиться, например, ко второму элементу вектора arrColor как arrColor[Green].
Не запрещается задавать индекс символами.
Физическая структура вектора представляется в машинной памяти последовательностью одинаковых по длине участков памяти (слотов), каждый из которых предназначен для хранения одного элемента вектора. Обычно элементы вектора располагаются в памяти в порядке возрастания адресов соответствующих им слотов. Дескриптор вектора может содержать такие поля, как имя вектора, адрес в памяти его начального элемента (т. е. первого слота), нижняя и верхняя границы индекса, тип элемента и размер слота. Физическая структура вектора A, объявленного выше, показана на рисунке 5.1.
Рисунок 5.1 Пример физической структуры вектора с базовым типом Integer
При доступе к любому элементу имя вектора и текущий индекс элемента преобразуются в физический адрес слота, в котором располагается этот элемент. Как видно из рисунка 5.1, логическая и физическая структуры вектора совпадают, и то и другое линейные последовательности элементов. Если в логической структуре при переходе от одного элемента к другому последовательному элементу индекс изменяется на единицу, то при переходе между последовательными элементами в физической структуре, адрес изменяется на величину, равную размеру слота базового типа.