Kest
Чтобы исключить недостатки реализации списка с использованием массивов каждый элемент списка размещается в динамической памяти и дополняется указателем на следующий элемент. При этом требуется дополнительная память.
Все переменные массивов, описываемые в разделе var, размещаются в памяти перед выполнением программы и находятся там постоянно, они называются статическими. Но во время выполнения программы в памяти могут размещать новые переменные и после их использования - удалять, освобождая память. Такие переменные динамические. Они не имеют имен и обращение к ним производится по их адресам в памяти. Для хранения адресов используются переменные особого типа - указатели. Различают указатели на целые(pi), вещественные(pr) переменные, на массивы(pm), записи и на любые типы данных. Существует 1 константа типа указатель: NIL, которая обозначает "пустой адрес". Переменная типа "указатель" определяет адрес динамической переменной. Для описания указателей в программах на Objet Pascal используется следующая конструкция:
Type
mas=array[1..10] of integer;
Var
pi:^integer;
pr:^real;
pm:^mas;
Значение пустого адреса можно присвоить любому указателю. Выделение памяти для динамической переменной производится процедурой NEW(указатель). Эта процедура резервирует необходимый объем памяти, адрес которого сохраняется в указателе. Освобождение памяти после использования -процедура Dispose(указатель).Список организованной динамической памяти можно представить:
Каждый элемент списка размещается в ячейке, которая содержит 2 поля.1 поле: элемент. 2 поле: указатель на следующий элемент. Первая ячейка определяет заголовок списка, элемента не содержит, но содержит указатель на 1 элемент. Позиция при такой организации списка отличается от номера элемента. Под позицией элемента понимается указатель на предыдущую ячейку списка, которая содержит указатель на заданный элемент.Описание абстрактного типа данных "список" имеет вид:
type
LIST=^cell;
cell=record;
element: el_type;
next: List;
end;
position=List;
Покажем реализацию некоторых операторов для переменных типа список:1) Создать пустой список:
Function MAKENULL (var L:List): position;
begin
New (L);
L^.next:= NIL;
MAKENULL:=L;
end;
2) Вставить элемент x в позицию p списка L.
Procedure INS(x:el_type, p:position var L:List);
Var
temp: position;
begin
temp:=p^.next;
New (p^.next); // Выделение памяти под ячейку
p^.next^.element:=x; // В нее записывается x
p^.next^.next:=temp;
End.
Рассматриваемый тип данных список показывает пример реализации однонаправленного списка, в котором указатель позволяет определить только следующий элемент, но не предыдущий. Существуют двунаправленные списки, в которых ячейка содержит 2 указателя, на следующий и на предыдущий элемент. При такой организации проще просматривать список в двух направлениях: прямом и обратном. Здесь в качестве позиции элемента может использоваться указатель на ячейку, содержащую данный элемент.Недостатком применения указателей является то, что они затрудняют обращение к элементам списка по их номеру и их не рекомендуется использовать при частых вставках и удалениях элементов
Ссылки по теме