Файл: Оперативные графические системы в автоматизации проектирования..pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 23.10.2024
Просмотров: 66
Скачиваний: 0
ii каждая пара (элемент, адрес связи) определяется пу тем индексирования на одну п ту же величину :в обоих массивах.
В рассмотренных методах представления элементов цепных списков адрес связи указывал на следующий эле мент цепочки. Цепной список с таким адресом связи можно назвать однонаправленным. Поиск элементов в таком списке ведется в одном направлении до последнего элемента. Такая организация списка достаточно проста
а
6
Рис. 6.8. Двухнаправлеиный цепной список: а — представление двухнаправлениого цепного списка символов; 6 — граф двухнаправлепно-
го цепного списка
и универсальна, и в случае обработки элементов списка строго последовательно затраты на продвижение по це почке сравнительно невелики. Иногда при работе со списками после обработки очередного элемента всегда обрабатываются соседние элементы оправа и слева. В этом случае оказывается полезным иметь двухнаправ ленный цепной список. Такой список можно представить симметрическим графом, две смежные вершины которо го всегда соединены двумя противоположно направлен ными дугами.
Двухнаправленный цепной список имеет два адреса связи на один элемент — прямой и обратный. Прямой адрес указывает на следующий элемент, обратный— на предыдущий элемент цепного списка. Двухнаправленный цепной список и его отображение в виде симметрическо го графа показаны на рис. 6.8, а, б.
С целью сокращения расхода памяти может оказать ся целесообразным использовать кольцевой список
173
(кольцо), в котором признак окончания списка заменяет ся адресом связи, указывающим на первый элемент кольца (рис. 6.9, а). Кольцо может быть представлено в виде контура в направленном графе, как это показано на рнс. 6.9, б.
Кольца являются особенно полезными тогда, когда элементы списка не представляют собой упорядоченную последовательность п возможен вход в список в любой
а
Е
Рнс. 6.9. Кольцевой список: а — представление кольцевого списка
символов; о — граф кольцевого списка
его точке. Так, при использовании светового пера для идентификации элемента выделяется лишь адрес данного элемента, а любая другая информация об этом элементе, его положение в структуре неизвестны. В этом случае оказывается возможным пройти по кольцу от данного элемента к любому другому элементу, а также к началу кольца с помощью информации, находящейся в самих элементах (адреса связи), не требуя дополнительных данных.
Во всех рассмотренных представлениях цепных спис ков в качестве элементов списка использовались простые величины (символы). Однако возможно применить цеп ные списки для связи блоков памяти, содержащих боль шее количество данных. В том случае если блоки имеют фиксированную длину, список блоков не отличается от списка простых величин. Таким же образом может быть построен однонаправленный, двухнаправлевный п коль цевой цепной списки. В элемент такого списка (рнс. 6.10) включается заголовок, в котором указывается длина блока, характеристика данных и т. д.
174
Распределение памяти. Организация цепных списков и операции, выполняемые над ними, предполагают дина мическое распределение памяти. При увеличении числа элементов в списке и образовании новых списков расход памяти увеличивается, при стирании списков память ос вобождается. В начальный момент, когда в памяти еще нет ни одного списка, организуется резервная область свободных ячеек, представляющая собой сплошной
АДРЕС СВЯЗИ
ЗАГОЛОВОК
ДАННЫЕ
Рис. 6.10. Блок цепного списка
блок памяти. По мере необходимости память из этой об ласти расходуется на создание списков, а при исключе нии списков освободившаяся память возвращается в эту область. В результате многочисленных пересылок резер вная область разбивается на множество отдельных бло
ков. По этой причине необходимо |
организовать область |
|||
свободных ячеек в цепной список, |
называемый списком |
|||
свободных ячеек. |
Элементы этого списка |
имеют такую |
||
же структуру, как п элементы |
создаваемых списков. Из |
|||
списка свободных |
ячеек берутся ячейки для построения |
|||
с. с. д., п в него |
возвращаются освободившиеся ячейки. |
|||
Однако не всегда является |
очевидным, |
освободилась |
ли память и можно ли ее передавать в список свободных ячеек. Например, в случае общих подсписков исключение элементов одного списка не означает освобождения па мяти, так как на эти элементы могут ссылаться элемен ты другого списка.
При стирании элемента В в цепном списке 1 (рис. 6.11), т. е. изменении адреса связи в элемент Б, ячейки элемента В нельзя передать в список свободных ячеек, так как при этом будет разрушен цепной список 2.
Таким образом, возникает необходимость в разработ ке способов поиска действительно освободившейся памя-
тн п присоединения ее к списку свободных ячеек. Этот процесс носит название «чистка» памяти.
Чистка памяти. Процесс чистки памяти может упро ститься в том случае, если ни на одни нз элементов цеп ного списка нет ссылок из других цепных списков. При этих условиях исключенный из списка элемент должен быть безусловно включен в список свободных ячеек. В другом простейшем случае точно известно, какие спи
ски ссылаются на исключаемый элемент. Тогда необхо димо во всех списках изменить адреса связи, указываю щие на исключаемый элемент, а сам элемент присоеди нить к списку свободных ячеек. Однако иногда процесс изменения адресов является длительным и целесообраз но оставить элемент в списках, отметив его специальным признаком («ключом»), т. е. исключить элемент логи чески.
В большинстве случаев в с. с. д. существуют общие подсписки и известно, сколько и какие списки указывают на данный элемент. Для решения проблемы чистки памя ти в данном случае обычно используются три различных метода [10].
При первом методе чистка памяти возлагается на программиста. В язык обработки списков включаются команды, позволяющие исключать списки и подсписки, а освободившуюся память передавать в список свобод ных ячеек. Однако такой способ является неудовлетвори тельным, так как вынуждает программиста постоянно следить за состоянием списков, подсписков и т. д.
Второй метод предполагает наличие в блоке данных числа, показывающего, сколько раз на данный элемент
176
произведено ссылок. В процессе выполнения программы проверяется это число, и при равенстве его нулю элемент включается в список свободных ячеек. Этот метод носит название «подсчета ссылок». В каждом элементе цеп ного списка выделяется поле, в котором размещается счетчик ссылок, показывающий количество адресов свя зи, указывающих на данный элемент. Всякий раз, когда новый элемент включается в цепной список, его счетчик ссылок устанавливается в единицу. Если создается адрес связи, указывающий на уже существующий элемент, то счетчик ссылок этого элемента увеличивается на едини цу, при изменении или исключении адреса связи счетчик ссылок указываемого элемента уменьшается на единицу. Когда счетчик ссылок элемента уменьшился до нуля, этот элемент включается в список свободных ячеек, а счетчик ссылок того элемента, на который указывал адрес связи данного элемента, уменьшается на единицу.
Наибольшее распространение получил третий метод, названный собственно «чисткой памяти». В этом случае память для построения цепных списков берется из списка свободных ячеек до тех пор, пока этот список не исчер пается. После этого ищутся в памяти те элементы, на ко торые нет ссылок и все они включаются в список свобод ных ячеек. В каждом элементе цепного списка выделяет ся специальный разряд занятости, использующийся в процессе чистки. Во всех элементах, которые берутся пз списка свободных ячеек, этот разряд устанавливается в нуль. Всякий раз, когда исчерпается список свободных ячеек, делаются два последовательных шага.
Ш а г 1. |
Отмечаются все нужные в данный момент |
элементы. |
Для этого все списки н подсписки структуры |
сканируются и во всех пройденных элементах разряд за нятости устанавливается в единицу. Этот процесс окан чивается при достижении последнего элемента структуры или ранее отмеченного элемента. В конце первого шага все нужные элементы будут отмечены, а следовательно,
те элементы, |
которые остались неотмеченными (разряд |
занятости равен нулю), являются ненужными. |
|
Ш аг 2. |
Заполняется список свободных ячеек. Для |
этого сканируется вся область памяти, отведенная под структуру, и всякий раз, когда встречается неотмеченный элемент, он присоединяется к списку свободных ячеек; когда встречается отмеченный элемент, его разряд заня-
12. Зак. 218 |
177 |
тости устанавливается в пуль, подготавливая тем самым элемент для участия в следующем цикле чистки.
Последний метод является универсальным способом чистки памяти, хотя и более длителен, так как требует просмотра всех элементов списков. Метод подсчета ссы лок выполняется быстрее, однако при этом увелнчнва-
Разряд занятости
Рис. 6.12. Цепной список символов до процесса уплотнения
ется расход памяти из-за выделения специального поля для счетчика, вместо одного-двух резервных разрядов.
Уплотнение элементов списка. В результате много численных чисток памяти элементы цепных списков и списка свободных ячеек оказываются разбросанными по полю памяти. Для уменьшения времени выборки элемен тов при передаче структуры во внешнюю память необхо димо произвести уплотнение элементов цепного списка. Уплотнение заключается в том, что использующиеся в данный момент цепные списки перемещаются таким образом, что элементы этих списков занимают один сплошной ма,сиив памяти, а элементы списка свободных ячеек — другой сплошной массив. Процесс уплотнения овязан с методами чистки памяти. Если применяется ме тод подсчета ссылок, то уплотнение можно вести в любое время. В случае использования метода собственно чист ки памяти, уплотнение проводится только после первого шага чистки, когда все нужные элементы окажутся отме ченными.
В качестве примера рассмотрим один из возможных алгоритмов уплотнения, который можно применить для цепных списков с элементами одинакового размера. Ос новная идея алгоритма заключается в том, что размеще ние в одной области всех нужных элементов, а в другой ненужных осуществляется путем перемены их местами, причем в ячейку, где ранее находился перемещаемый элемент, ставится адрес той ячейки, в которую он пе ремещен. Произведем уплотнение цепного списка, имею щего элементы одинаковой длины и объединяющего че тыре символа ЦЕПЬ (рис. 6.12).
178
Пусть |
элементы этого списка будут размещены |
в области |
памяти размером в 10 ячеек. Во время скани |
рования этой области на первом шаге чистки все элемен ты списка будут отмечены как нужные, т. е. разряд заня тости установлен в единицу. Все ненужные элементы будут иметь указатель занятости равный нулю (рис. 6.13, а). В процессе уплотнения используются две дополни тельные ячейки, назовем их ВЕРХ и НИЗ. Первоначаль но в ячейке ВЕРХ содержится адрес, указывающий на верхнюю ячейку области, а в ячейке НИЗ — на нижнюю ячейку области (рнс. 6.13, а). Затем путем последова тельного уменьшения на единицу содержимого ячейки ВЕРХ сканируется область памяти сверху вниз до тех пор, пока не встретится ненужный элемент; с помощью ячейки НИЗ сканируется область снизу вверх до нужно го элемента. Нужный элемент при этом помещается по адресу, указанному в ячейке ВЕРХ, а адрес этой новой ячейки (значение ячейки ВЕРХ) помещается в старую ячейку, указанную адресом в ячейке НИЗ, и процесс ска нирования продолжается (рис. 6.13, б, в). Первая фаза уплотнения оканчивается, когда значения адресов в ячейках ВЕРХ и HEI3 сравняются (рнс. 6.13, г). При этом в ячейке НИЗ содержится последний адрес блока нужных элементов. Во второй фазе сканируется область сверху до границы блока нужных элементов (адрес НИЗ), и вместо адресов связи тех элементов, которые указывают за границу этого блока (т. е. значение адре сов меньше, чем НИЗ”), подставляются адреса из старых ячеек, причем старые ячейки отмечаются как ненужные (рис. 6.13, Р). Из рис. 6.13, д видно, что после уплотнения первоначально разбросанные в памяти элементы цепно го списка оказались компактно упакованными в после довательные ячейки одного блока, а свободные (ненуж ные) элементы занимают ячейки другого блока.
Обработка цепных списков. При обработке списков одной из важных операций является хранение и поиск элементов в списочной структуре. Для того чтобы найти элемент в цепном списке, необходимо пройти по всей це почке адресов связи до нужного элемента. Этот элемент определяется своим идентификатором, записанным в определенном поле элемента. При включении элемента в цепной список адрес ячейки, в которую он записывает ся, не зависит от идентификатора элемента, а онреде-
12* |
179 |