- •Типы и структуры данных. Опредления, классифиация.
- •Простые типы данных, операции над ними. Сильная и слабая типизация.
- •Массивы. Операции, способы предсавления, сложность операций.
- •Записи. Операции над ними, способы представления, сложность операций.
- •Объединения. Операции, представление. Сложность операций.
- •Множества. Операции, способы представления, сложность операций.
- •Последовательности вкратце
- •Линейные списки
- •Очереди.
- •Линейный список, сложность операции o(1)
- •Динамические струкутуры данных. Работа динамической памяти в c.
- •Деревья. Определения, классификация, способы представления.
- •Двоичные деревья, операции.
- •Дерево поиска. Основные операции, вычисление средней длины пути.
- •Виды сбалансированных деревьев, достоинства и недостатки.
- •Дерево оптимального поиска
- •Красно-черные деревья.
- •Splay-деревья.
- •Асоциативные массивы и хэши
Динамические струкутуры данных. Работа динамической памяти в c.
Динамические структуры данных
Во многих задачах требуется использовать данные, у которых конфигурация, размеры и состав могут меняться в процессе выполнения программы. Для их представления используют динамические информационные структуры. К таким структурам относят:
линейные списки (однонаправленные, двунаправленные, циклические);
стек;
очередь;
деревья;
динамические массивы (нерекурсивная).
Они отличаются способом связи отдельных элементов и/или допустимыми операциями. Динамическая структура может занимать несмежные участки оперативной памяти.
Динамические структуры широко применяют и для более эффективной работы с данными, размер которых известен, особенно для решения задач сортировки.
Использование динамических величин предоставляет программисту ряд дополнительных возможностей. Во-первых, подключение динамической памяти позволяет увеличить объем обрабатываемых данных. Во-вторых, если потребность в каких-то данных отпала до окончания программы, то занятую ими память можно освободить для другой информации. В-третьих, использование динамической памяти позволяет создавать структуры данных переменного размера.
Память:
программы |
данные |
|
heap/куча |
P
Динамическое распределение памяти
Функция p=выделить(N) возвращает указатель на объект памяти длиной N,
В Си – p=new(N) (неопределенный тип указателя).
Проблемы:
Типизация указателя.
В языка строгой типизации int *p и char*g - не эквивалентны => необходимо преобразование типа.
Освобождение выделяемой памяти
Явный механизм (программист) – функция уничтожить(р);
Нет явного механизма (ОС) – уничтожается, когда отсутствуют ссылки на объект, можно осуществлять через таймер, по завершению программв, при переполнении.
Проблема висящих объектов (когда один динамический объекс ссылается на другой динамический объект)
В памяти остаются объекты с отсутствием ссылок. Уничтожив этот объект, можно потерять ссылки на все его подобъекты.
Проблема висящих указателей (остются ссылки на уничтоженные объекты);
Фрагментация памяти
heap
P1
P2
P3
P4
P5
Уничтожим р3 и р5 – на новый объект хватит памяти, но не будет цельного
куска.
Правила при работе с динамической памятью при наличии явных механизмов уничтожения:
Не допускать наличие висящих объектов. Для этого сначала надо уничтожить все вложенные объекты.
Не допускать висящих ссылок, т. е. после уничтожения объекта уничтожить и ссылку на него - p=NULL.
Минимизировать фрагментацию. Для этого нужно уничтожать объекты в порядке обратном порядку их создания: р5 – р4 – р3.
Реализация механизма динамической памяти в C:
Выделение динамической памяти через функцию void *malloc(size_t size).
Например, если нужно 10 элементов массива, то:
int A;
A=(int*)malloc(10 * sozeof(int)).
Размер требуемой памяти size_t size может быть больше, чем требуется (для выравнивания)
Функция void *calloc(size_t num, size_t size);
все значения в полученной памяти нулевые.
void free (void*p)
указатель указывает на ранее захваченный блок памяти операциями malloc, calloc, realloc, т. е. число освобождаемых байтов = числу байтов, полученных при захвате
преобразование int в void free((void *) A);
Функция void *realloc(void*p, size_t new size)
Изменяет размер ранее захваченного блока памяти, p – указатель на начало блока, size – размер в байтах. Блок может быть передвинут в памяти при изменении размера.