Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Двусвязные списки
В двусвязных списках базовый комбинированный тип S для указателей типа P будет иметь два адресных поля: поле ls ссылки на следующую запись списка и поле lp ссылки на предыдущую запись списка. Описание двусвязных списков аналогично приведенному выше (для односвязных списков) с отличием в структуре S: P=^S; {тип указатель записи базового типа S} S=Record {базовый тип для указателей типа Р} ls: P; {поле типа Р ссылки на следующую запись} lp: P; {поле типа Р ссылки на предыдущую запись} Dt: Z {поле типа Z записи данных} end; При работе с одно- и двусвязными списками нужно уметь добавлять элементы в любое место списка, удалять заказанный элемент из списка и перемещаться по списку с целью поиска или выбора информации из списка. Необходимо определять, пуст ли список в данный момент. Обычно считается, что список пуст, если в нем имеется только звено заголовка и нет ни одного звена с данными. При работе с такими списками в начале необходимо создать заголовок (процедурой New), а в конце программы этот заголовок должен быть удален процедурой Dispose. Добавление звена в список и удаление из списка обычно оформляется в виде процедур. Перемещение по списку чаще всего выполняется с помощью итеративного цикла (" …Пока не достигнем звена с нужными данными или не просмотрим весь список…"). Ниже приведены некоторые примеры процедур для разных видов списков. Проверка " пуст ли список" обычно нужна для того, чтобы упростить процедуры работы со списками, так как с пустыми списками не все операции возможны. Для линейных и кольцевых списков с заголовком вне кольца, проверяется ссылка из заголовка на следующее звено. Если Uz^.ls=nil, то список пуст. Для кольцевых с заголовком в кольце – если Uz^.ls=Uz, то список пуст. Пример процедуры добавления элемента в линейный односвязный список (определяемый указателем Uz) после звена, заданного текущим указателем (U). procedure PutS1(Var U: P; E: Z); var q: P1; { Завели рабочий указатель } begin new(q); { Создаем новое звено, пока вне списка } q^.Dt: =E; { заполняем его информацией } q^.ls: =U^.ls; {подцепляем к новому звену конец списка за U } U^.ls: =q {подцепляем к началу списка (до U) новое звено} end; Если добавлять элемент нужно в начало списка (на которое ссылается заголовок списка), при вызове процедуры в качестве первого параметра приводится указатель заголовка списка. Пример процедуры удаления элемента, заданного текущим указателем (U) из линейного двусвязного списка.
procedure DelS2(Var U: P); var q: P; { Завели рабочий указатель } begin q: =U^.lp; {q указывает звено перед тем, на которое указывает U } q^.ls: =U^.ls; {в звене q^ меняем ссылку на следующее звено – за U^} if U^.ls< > nil then {если удаляемое звено – не последнее, то } begin q: =U^.ls; { в звене за удаляемым } q^.lp: =U^.lp { меняем ссылку на предыдущее звено } end; dispose(U); { собственно удаление звена } U: =nil { очистка указателя на удаленное звено } end; После срабатывания этой процедуры текущий указатель перестает указывать на что-либо (равен nil). Пример процедуры удаления элемента, заданного текущим указателем (U) из кольцевого двусвязного списка. procedure DelS2K(Var U: P); var q: P; begin q: =U^.lp; q^.ls: =U^.ls; q: =U^.ls; q^.lp: =U^.lp; dispose(U); U: =nil; end; Выбор данных из списка производится без изменения списка, путем ссылки на информационную часть нужного звена: U^.Dt. Чтобы добраться до нужного звена списка, по нему приходится последовательно перемещаться (в цикле, начиная от начала или от текущего звена). Так же как при работе с массивом, для перехода от элемента A[i] к следующему элементу необходимо выполнить i: =i+1. При работе со списком следует использовать оператор U: =U^ls. Создав список (в цикле, используя процедуру добавления звена) и поработав с ним, необходимо в конце программы удалить его (также, в цикле, используя процедуру удаления элемента списка, пока он не станет пустым). После этого не забыть удалить заголовок списка.
|