Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на языке Паскаль в среде Turbo Pascal версии 6 и 7 (Курс лекций). Воронов Г.И.Санкт-Петербург 2010г.doc
Скачиваний:
90
Добавлен:
15.04.2015
Размер:
754.69 Кб
Скачать

Списочные данные

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

Такие составные данные носят название списков.

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

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

Ниже приведены схемы различных видов списков записей. На них символами "*" отмечены поля ссылок. Стрелками показаны связи между записями. Поля данных заглавных звеньев обычно используются для хранения общей информации о списках.

Односвязные списки

Пример организации односвязного списка приведен ниже.

Type

Z=Record {комбинированный тип для данных}

a: String; {строковое поле}

b, c: Integer; {поле целых чисел}

d: Real {поле вещественных чисел}

end;

P=^S; {тип указатель записи базового типа S}

S=Record {базовый тип для указателей типа Р}

ls:P; {поле типа Р ссылки на следующую запись}

Dt:Z {поле типа Z записи данных}

end;

В этом примере типы Z и S введены для описания переменных  записей, содержащих в своих полях a, b, c, d данные, соответствующие описанным типам полей. P  тип указатель для динамических переменных базового типа S, т.е. значения переменных типа P будут адресами переменных типа S.

Наличие у комбинированной переменной типа S адресного поля ls типа P позволяет включать в состав записи ссылку на последующую запись и хранить таблицы в памяти машины в виде динамических списков связанных записей.

Var

Dt:Z; {запись данных}

Uz,U:P {указатели заглавного и текущего звеньев списка}

Двусвязные списки

В двусвязных списках базовый комбинированный тип 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 , то список пуст.

Выбор данных из списка производится без изменения списка, путем ссылки на информационную часть нужного звена: U^.Dt. Чтобы добраться до нужного звена списка, по нему приходится последовательно перемещаться (в цикле, начиная от начала или от текущего звена). Так же как при работе с массивом, для перехода от элемента A[i] к следующему элементу необходимо выполнить i:=i+1.

При работе со списком следует использовать оператор U:=U^ls.

Создав список (в цикле, используя процедуру добавления звена) и поработав с ним, необходимо в конце программы удалить его (также, в цикле, используя процедуру удаления элемента списка, пока он не станет пустым). После этого не забыть удалить заголовок списка.