Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


Построение и использование списков в динамической памяти.




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

GetMem(Size: Integer; out P: Pointer); - выделение памяти;

FreeMem(P: Pointer); - освобождение памяти

Часто при работе с динамической памятью используются цепочки, очереди и списки. Они обеспечивают гораздо большую гибкость чем массивы, так как у последених элементы связаны жесткой связью, упорядочены по номерам. Цепочка – это структура из звеньев, где звено – это структура содержащая поле для указания на объект и поля длz указания на другие звенья. Цепочки бывают однонаправленные и двухнаправленные. В однонаправленной цепочке каждый элемент указывает только на следующий за ним и движение по цепочке возможно только в одном направлении, в двунаправленной Цепочке – в звеньях храняться указатели на следующий и предыдущий элемент и движение возможнов обоих направлениях.

Общая структура звеньев может выглядит так:

Однонаправленный список:

Pchain = ^Tchain;

Tchain = record

Element: Telement;

Next: Pchain; End;

Двухнаправленный список:

Pchain = ^Tchain;

Tchain = record

Element: Telement;

Next: Pchain;

Prev: Pchain; End;

Здесь Pchain – указатель (ссылочный тип) на звено цепочки, а поле элемент является объектом, цепочка которых организуется. Для доступа к элементам цепочки необходимо иметь хотя бы указатель на первый элемент или на последний.

Методы использования динамической структуры отличаются. В зависимости от использования могут использоваться дополнительные указатели, например на текущий элемент цепочки. Однако в общем организация в памяти будет выглядеть таким образом (см. рисунок):

При этом цепочка, изображенная на первом рисунке с указателем на первый элемент называется стеком (LIFO – last input first output) – так как такая организация, реализует алгоритм, когда последний размещенный элемент, извелекается первым. Если использовать еще указатель на последний элемент, то можно организовать очередь, FIFO – first input first output, когда первый размещенный элемент будет первым извлечен. Алгоритм и организация полностью зависят от желаний программиста.

Часто возникает необходимость организовать доступ к произвольным элементам цепочки. При этом необходимо знание не только следующего звена, но и предыдущего для перемещения в двух направлениях. Такие цепочки называются списками. Их организация в памяти приведена на рисунке выше.

Основными функциями для работы являются помещение и извлечение из списка очередного элемента. Рассмотрим общий алгоритм этих функций напримере стека:

Если надо добавить элемент он добавляется впереди первого элемента, при этом указатель на первый элемент переключается на новый элемент, а указателю на следующий элемент у нового элемента присваивается значение старого первого элемента. При удалении – удаляется первый элемент, а указатель первого элемента переключается на указатель на следующий элемент удаленного элемента.

При этом пользователю необходимо следить за корректным значением всех указателей в цепочке, вовремя их обнулять. Однако алгоритм остается похожим на приведенный выше. Т.е. при добавлении создается новый элемент, его поля Next и Prev получают указатели на элементы в разрыв, которых идет вставка (возможно вставка в пустой список или в начало (конец) – в этом случае они нулевые).А эти элементы в свою очерель меняют свои указатели (следующий для прудыдущего и предыдущий для следующего) на вставляемый. Также корректируются указатели на первый, последний и текущий элементы.

При удалении – сам элемент удаляется (память его освобождается). Однако перед этим, его “соседи” связываются в цепочку между собой.

 


 


Поделиться:

Дата добавления: 2015-04-18; просмотров: 125; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.007 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты