Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги из ГПНТБ / Оперативные графические системы в автоматизации проектирования

..pdf
Скачиваний:
4
Добавлен:
19.10.2023
Размер:
6.87 Mб
Скачать

10

0

Верх

90

1 Е

0

0

9

 

0

П

 

 

 

 

1

 

 

 

3

 

/

Ь

 

 

 

2

 

0

 

 

 

 

1

 

1 J L -

 

 

Низ

/

Ц

 

 

1

ц

 

0

 

 

 

1

ь .

h \

1

Е

 

 

1

Е

0

 

 

 

0

 

1 | \Bepx

0

 

 

 

0

 

 

0

 

 

 

0

П

 

/

л

 

 

1

? = J -№ I

/

ь

 

-|ЖГ] 1

 

0

 

 

____ | Лн.СП

0

 

__J

0

 

 

1

 

1

и

/

и

7

Ь

1

ь

/

Е\

1

Е

/

О

1

П

0

г г ч ж

0

0.

 

0

L

 

0

/

 

0

0\

_____ I

0

ЧН.СП 1

0

Рис. 6.13. Уплотнение

цепного

списка:

а — представление

еппскг

после первого

шага

чистки;

б,

в — сканирование области

памяти;

г — окончание

первой

фазы

уплотнения;

д — представление

списка

 

пссле

второй

фазы уплотнения

 

ляется программой распределения памяти, которая вы­ бирает этот адрес из списка свободных ячеек. Если новый элемент включается в начало списка, то на место адреса связи этого элемента ставится адрес Л11ХП, который за­ тем изменяется на адрес нового элемента. Еслш новый элемент включается куда-то в середину списка, то снача­ ла находится предшествующий элемент списка, после которого требуется включить новый элемент, а затем

0

п

г

к

А

1

1

 

_1

Н

 

 

 

Г

 

 

 

I

__I

 

 

Рис. 6.14. Включение нового элемента в список символов

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

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

181

Определение узлового списка. Узловой список опреде­

ляется конечным

связанным графом без контуров G —

= {А, U), состоящим из непустого

множества вершин

А = В U С ( А Ф 0 )

и множества дуг

U, соединяющих

смежные вершины, причем висячие вершины такого гра­ фа В = {Ви В , ..., Вк) отображают атомы (неделимую с точки зрения операций над списком структуру). Для вер­

шин графа узлового списка справедливы следующие вы­ ражения:

U tl = 0;

U+ > 1;

i = 1;

UCi 1.

Все вершины графа делятся на ряд уровней и соединяют­ ся горизонтальными и вертикальными дугами. Горизон­ тальные дуги, инцидентные вершинам С={ Си С2, С3, ....

Ст}, позволяют осуществить перемещение вдоль одного уровня графа (вдоль одного подсписка), а вертикальные дуги определяют переход на другой уровень графа (пере­ ход к подсписку) (рис. 6.15).

Таким образом, совокупность вершин, связанных го­

ризонтальными дугами, соответствует одному под­ списку.

182

Блоки узлового списка состоят из двух полей, в пер­ вом из которых помещается атом или адрес связи, опре­ деляющий подсписок, а во втором— адрес связи, указы­ вающий на следующий элемент списка.

Внутренняя структура списков может быть также представлена с помощью символьного выражения в виде последовательности атомов, разделенных точками и скоб­ ками [11, 12].

Рис. G.1G. Представление узлового списка

С помощью выражения (сс-(3) можно описать блок, в первом поле которого находится а, а во втором — |3. При этом точка указывает на нахождение двух величин в од­ ном блоке, а скобки обозначают адрес этой ячейки.

Если во втором поле находится адрес другого блока, в котором записан следующий элемент списка р, и этот блок является последним в списке, то выражение (сс.(|3)) определит данный список.

Представление узлового списка в памяти. Используя представление списочной структуры, узловой список мо­ жет быть описан выражением (/1. ( (В. (С)) .D)). Такой список размещается в памяти так, как это показано на рис. 6.16. Размещение в одном блоке атомов и адресов связи является не совсем удачным. Возникают трудности в определении, находится ли в первом поле атом пли ад­ рес связи. В большинстве случаев для хранения атома требуется больший размер поля, чем для адреса связи. Однако одинаковое распределение памяти приведет к излишнему расходу ее, так как в сложной структуре на­ много больше адресов связи, чем атомов.

Чтобы избежать этого, список на рис. 6.16 можно пре­

образовать таким образом, чтобы

атомы занимали от­

дельные блоки (рис. 6.17, а). Для

этого в первом поле

вместо атома размещается адрес связи, определяющий блок с атомом. Блоки с атомами содержат идентифика­ тор (—1 )— дополнительный признак, позволяющий от-

183

лпчить блоки с атомами от других блоков. Граф этого списка представлен на рис. 6.17,6.

Узловые списки, подобно цепным, могут быть двухнаправленнымп. В этом случае каждый список определя­ ется двумя адресами связи: один, указывающий на пер­ вый элемент, другой — на последний элемент списка. Каждый элемент определяется четырьмя адресами свя­ зи: одни, указывающий на предыдущий, второй — на

А

В

 

9 ;

Рис. 6.17. Узловой список с выделенными в отдельные блоки атома­ ми: а — представление узлового списка; б — граф узлового списка

последующий элемент; два других адреса связи указы­ вают на первый и последний элементы подсписка, ответ­ вляющегося от данного элемента соответственно. Двухнаправлеиный узловой список изображен на рис. 6.18.

Однако такая структура излишне загромождает па­ мять, требуя двух адресов связи для каждого списка н подсписка. Для упрощения двухнаправленный узловой список можно преобразовать в двухнаправленное кольцо [13]. Каждый элемент списка представляется блоком, состоящим из двух ячеек (рис. 6.19, а). Первая ячейка всегда состоит пз трех полей, которые содержат: ИД — идентификатор блока, ПАС — прямой адрес связи, ука-

184

зывающпй на последующий

блок, п ОАС — обратный

адрес связи, указывающий па предыдущий блок в списке.

Идентификатор в первой

ячейке блока определяет, как

интерпретируется данный

блок.

Блок, определяющий ато­

мы, имеет ИД = 0, а сам атом располагается

во второй

ячейке блока. При И Д =1 блок определяет

подсписок.

Вторая ячейка этого блока имеет идентификатор, равный

Рис. 6.18. Двухмаправленнын узловой список

О, и оба адреса связи указывают на заголовок подсписка. Каждый список имеет заголовок, который определяет список; идентификатор заголовка равен 2, а прямой и об­ ратный адреса связи указывают на первый п последний блоки списка. Во вторую ячейку заголовка может быть включен счетчик ссылок (СС) для чистки памяти. Спис­ ки (А. (В)) и (С. ((Л .(£)))) могут быть представлены с помощью двухнаправленных колец так, как это показа­ но на рис. 6.19,6 и 6.19. б соответственно.

Узловой список можно преобразовать в однонаправ­ ленное кольцо, заменяя признак последнего элемента на адрес связи, указывающий на первый элемент данного уровня. Появляющиеся при этом дополнительные дуги образуют на графе списка контуры (рпс. 6.20). Из рас­ смотрения графа можно заключить, что структура с од­ нонаправленными кольцами позволяет осуществить переход от любой вершины к вершине нижнего уровня,

185

Рис. 6.19. Узловой список с двухиаправлеипымн кольцами: а — струк­ тура блоков списка; б — представление списка ( А . ( В)); в — пред­

ставление списка (С .((/1 .(б ))))

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

Рис. 6.20. Граф узлового спи-

Рис. 6.21. Граф узлового спи­

ска с однонаправленными коль-

ска (A . ( B . ( C . ) ) . ( D ))

цамп

 

в последних вершинах каждого подсписка данного уров­ ня записывается адрес связи, указывающий на вершину верхнего уровня, с которой связан данный подсписок [14]. Граф узлового списка (А.((В.(С)) .(D))) с допол­ нительными дугами представлен на рис. 6.21. Такая структура позволяет пройти слева направо по всем вер­ шинам данного уровня, начиная с первой вершины пер­ вого уровня к вершинам нижних уровней и обратно, об­ ходя при этом все атомы, расположенные в висячих вер­ шинах.

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

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

Чистка памяти. Процесс чистки памяти для узловых списков усложняется по сравнению с цепными. Наличие сложных связей в структуре затрудняет поиск действи-

187

тсльно освободившихся блоков, не входящих в одни под­ список. Для узловых списков применимы те же методы, что и для цепных: подсчет ссылок и собственно чистка памяти.

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

Рмс. 6.22. Чистка памяти с помощью подсчета ссылок

весь список (заголовок и элементы) передается в список свободных блоков, а во всех заголовках, на которые ука­ зывали адреса связи элементов исключаемого списка, счетчики ссылок уменьшаются на единицу,. Список, вклю­ чающий два подсписка с общими элементами (А. (В. ((C)))) и (С.((Л.В))) с соответствующими значениями счетчиков ссылок, приведен на рис. 6.22.

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

188

димо отметить элементы во всех списках и подсписках структуры.

В качестве примера рассмотрим алгоритм чистки па­ мяти в случае применения однонаправленного узлового списка [10]. Приведенный алгоритм является эффектив­ ным как по объему рабочей памяти, так и по количеству проходов по одним и тем же элементам списков и при­ годен для прохождения по элементам любой списочной структуры с любым числом адресов перехода к подспис­ кам.

Каждый элемент с.с.д. представляется блоком, со­ стоящим из одной ячейки, разделенной на 4 поля. В поле, названном СВЯЗЬ, содержится адрес связи, указываю­ щий на следующий элемент списка. Поле ЗАГОЛОВОК содержит атом или адрес перехода к подсписку. Два поля ЗНАК и УКАЗАТЕЛЬ ПЕРЕХОДА используются специально для алгоритма чистки памяти. На рис. 6. 23, а приведен список {А. ((£>. (Е. (...).В. (С))), который необ­ ходимо пройти в первом шаге чистки. Первоначально знак всех элементов положительный. При прямом прохо­ де по элементам списка (от качала к концу) игнориру­ ются переходы к подспискам, адреса связи пройденных элементов только реверсируются, и в поле ЗНАК этих элементов записывается минус. Реверсирование адресов связи, т. е. изменение прямых адресов связи на обрат­ ные, позволяет в случае однонаправленного списка вер­ нуться к заголовку списка в процессе чистки памяти. Первый проход заканчивается в том случае, если встречен элемент с признаком конца списка пли очеред­ ной элемент имеет в поле ЗНАК минус, показывающий, что этот элемент входит в подсписок ранее пройденного списка. В результате прямого прохода списочная струк­ тура представляется так, как показано на рис. 6.23, б. После окончания прямого прохода начинается обратный проход (от конца списка к началу), при котором восста­ навливаются адреса связи и проверяется поле ЗАГОЛО­ ВОК на наличие в нем адреса перехода к подсписку. Если обнаружен элемент с адресом перехода, то его УКАЗАТЕЛЬ ПЕРЕХОДА устанавливается в единицу (рис. 6.23, в) . После этого начинается прямой проход подсписка и выполняются те же действия, что и при пря­ мом проходе списка. На рис. 6.23, г приведен подсписок после прямого прохода.

189

Соседние файлы в папке книги из ГПНТБ