Динамические структуры данных




Переменные типа «указатель» обычно используют при реализации динамических структур данных. Динамические структуры данных могут быть организованы линейно, в виде дерева и в виде сети.

Линейная динамическая структура представляет собой изменяемую последовательность элементов. Частными случаями таких структур являются:

· стеки, в которых разрешено добавлять элементы только в конец и удалять только последние элементы (рис. 7а);

· очереди, в которых добавление элементов осуществляется в конец, а удаление – из начала (рис. 7б);

· деки, которые допускают добавление и удаление элементов и с начала и с конца (рис. 7в);

В древовидной структуре каждый элемент (вершина) ссылается на один и более элементов следующего уровня (рис.7г). В сетевой структуре никаких ограничений на связи элементов не накладывается (рис. 7д).

 

 

Рис. 7

Линейные динамические структуры, такие как стеки, очереди и деки, при известном максимальном количестве элементов можно реализовать в виде динамических или статических одномерных массивов. В противном случае, а также для представления остальных структур (древовидной и сетевой) используют списки.

Списком называют структуру, в которой помимо данных хранятся также адреса элементов. Элемент списка состоит из двух частей: информационной, содержащей данные, и адресной, где хранятся указатели на следующие элементы. В зависимости от количества полей в адресной части и порядка связывания элементов различают линейные односвязные списки и линейные двусвязные списки.

Линейные односвязные списки – единственное адресное поле содержит адрес следующего элемента, если следующий элемент отсутствует, то в адресное поле заносят константу nil. Ниже приведена структура односвязного списка (рис.8), т.е. связь идет от одного элемента списка к другому в одном направлении. Здесь поле D – это информационное поле, в котором находятся данные (любой допустимый в языке Паскаль тип), поле N (Next) – указатель на следующий элемент списка.

Каждый список должен иметь следующие указатели: Head – голова списка, Cur – текущий элемент списка, иногда в односвязных списках также используется указатель Tail – хвост списка (в двусвязных списках он используется всегда). Поле указателя последнего элемента списка является пустым, в нем находится специальный признак nil, свидетельствующий о конце списка и обозначается перечеркнутым квадратом.

Для описания элементов списка используют записи, например, элемент односвязного списка с двумя информационными полями и одним адресным полем может быть описан следующим образом:

Type pe=^element; {тип указатель}

element=record

name:string[16]; {информационное поле 1}

telefon:string[15]; {информационное поле 2}

p:pe; {адресное поле}

end;

Односвязный список отличается тем, что пройти по нему можно только в одном направлении — от начала в конец списка. Это оказывается достаточно неудобно, поэтому гораздо большее распространение получили двусвязные списки.

Линейные двусвязные списки – каждый элемент содержит адреса предыдущего и последующего элементов, соответственно, первый элемент в качестве адреса предыдущего, а последний – в качестве адреса следующего элемента содержит nil (рис. 9).

Элемент двусвязного списка описывается двумя адресными полями, например:

Type pe=^element; {тип указатель}

element=record

name:string[16]; {информационное поле 1}

telefon:string[15]; {информационное поле 2}

back:pe; {адресное поле «предыдущий»}

next:pe; {адресное поле «следующий»}

end;

У любого списка имеется хотя бы один указатель, размещенный в статической памяти, который содержит адрес первого элемента списка или константу nil, если список пуст. Достаточно часто используют дополнительные указатели, в которых хранят адреса других элементов, например, адрес текущего элемента, адрес последнего элемента и т.п. Эти указатели также описываются как «указатели на элемент», например:

Var first, last, q:pe;

В процессе выполнения программы динамические структуры создаются, обрабатываются и уничтожаются.

Линейные списки в отличие от одномерных массивов позволяют:

· работать с произвольным количеством элементов, добавляя и удаляя их по мере необходимости;

· осуществлять вставку и удаление записей, не перемещая остальные элементы последовательности.

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

 
 

 

 


Рис.10

Недостатком этих структур является то, что при поиске элемента по номеру приходится просматривать все ранее расположенные элементы, в то время как в одномерном массиве возможен прямой доступ к элементу по индексу.

При работе с линейными списками используются основные операции:

· создание списка;

· добавление нового элемента в список: в голову списка, в хвост списка, после текущего элемента списка, перед текущим элементом списка;

· удаление элемента из списка;

· обход списка с целью его обработки;

· поиск узла в списке;

· переход на узел в списке по номеру от начала и другие операции.

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

Описание:

Type

tstud=record

fam:string[30];

group:string[10];

stip:real;

end;

Node=^List; //узел списка – это есть указатель на список

List=record

Info:tstud;

Back:Node; //Указатель на предыдущий элемент списка

Next:Node; //Указатель на следующий элемент списка

end;

Var

t, h,cur:node; st:tstud;

Создание списка. При создании списка нужно выполнить следующие действия (рис.11):

· выделить память;

· «обнулить» указатели на предыдущий и последующий элементы;

· определить указатели на голову, хвост и текущий элемент списка;

· внести в информационную часть списка данные.

 
 

 


Рис. 11

Function CreateList(st:tstud; Var H,T,C: Node): Node;

Var p: Node;

Begin

New(p);

p^.next:=nil;p^.back:=nil;

H:=p;T:=p;C:=p;

p^.Info.fio:=st.fio;

p^.Info.group:=st.group;

p^.Info.stip:=st.stip;

CreateList:=p;

End;

В результате выполнения этой функции будет создан список, содержащий одну запись.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-04-04 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: