Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Списочные структуры

Статическая реализация графов. Проблема фрагментации памяти.

До сих пор в реализации абстрактных типов мы старались жёстко зафиксировать некоторую нумерацию компонентов этого типа, связав её с естественной нумерацией самого массива. Такой подход не позволяет эффективно реализовать характерные для динамических типов операции вставки и удаления компонентов. Это хронический дефект массивов даже в их основной роли – хранение последовательностей.

Упражнение. Написать процедуры вставки и удаления символа и слова в тексте.

Дилемма: Либо тратить на не имеющие логического смысла технические сдвиги – дефрагментацию памяти, либо мириться с дырками фрагментированной памяти.

Начальная идея проста – ставить новые компоненты не в конец или начало памяти (массива), а на первое попавшее свободное место.

 

  a5 a4   a1 a2   a3 a6  

 

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

1 2 3 4 5 6 7 8

‘а’ ‘н’     ‘б’   ‘а’ ‘н’

2 7 1 8 Æ

 

5 – индекс 1-й буквы

Æ - специальное значение – признак конца списка.

Второй вариант – функция предшествования. Получаем понятия прямого, обратного и двукратного списков.

 

succ succ

последовательность одна, но автоматы разные.

pred pred

 

Общая схема реализации автомата как списка.

Атрибуты вершин графа.

На каждую стрелку отдельное поле, хранящее указатель на вершину, к которой ведёт эта стрелка.

 

Светофор


 

 


1 2 3 4 5 6 7 8

    К   З   Ж  

5 7 3

7 5

 

type tIndex=1..nMax;

tList=record

content:array[tIndex] of tNode;

head:tIndex;

end;

tNode=record

info:tInfo; {Атрибуты вершины}

next:tIndex;

end;

tGraphNode=record

info:tInfo[tIndex] of tNode;

left,right:tIndex;

end;

Варианты – перечень полей-указателей. Например, для бинарного дерева – left,right:tIndex. Либо массив-указатель, либо список.

Новый способ требует больше памяти. Окупится ли «жертва» эффективной вставки и удаления? Убедимся в этом (оставим на время проблемы, связанные с обработкой кучи).

Задача. Включить в список List компоненту x после компоненты.

 

procedure Include(var List:tList;x:tInfo;AfterPtr:tIndex);

var NewPtr:tIndex;

begin

{Взять первый свободный индекс NewPtr из кучи}

GetHeap(List,NewPtr); After NewPtr

with List do ¯ ¯

ai   x  

 

 

begin

content[NewPtr].next:=content[AfterPtr].next;

content[AfterPtr].next:=NewPtr;

content[NewPtr].info:=x;

end;

end;

 

Замечание: процедура Include корректно работает, если известна ссылка на предыдущую компоненту, после которой надо вставлять.

Техническая проблема: она не может включать в пустой список. Не хочется писать отдельную процедуру для включения в пустой список. Проверять же непустоту списка в процедуре Include неэффективно.

Решение: расширить тип Index до 0..nMax и при инициализации списка поставить в него фиктивную нулевую компоненту («болванчик» или «фантом»).

procedure Init(List:tList);

begin

with list do

begin

content[0].next:=0;

head:=0;

end;

{Инициализировать кучу}

end;

{Удаление элемента из списка, стоящего после компоненты AfterPtr}

 

procedure Exclude(var list:tList;AfterPtr:tIndex);

 

 

AfterPtr

¯ j

ai+2
ai+1   j2
 
ai
ai   j1
               
       

 


 

­ (удаление)

 

 

{Работает в предположении, что удалённая компонента существует}

var ThisPtr:tIndex;

begin

with list do

begin

ThisPtr:=content[AfterPtr].next;

content[AfterPtr].next:=content[ThisPtr].next;

{Сборка мусора – возвратить освободившуюся компоненту в кучу}

PutHeap(List,ThisPtr);

end;

end;

 

<== предыдущая лекция | следующая лекция ==>
Статическая реализация деревьев | Обработка кучи
Поделиться с друзьями:


Дата добавления: 2014-01-05; Просмотров: 296; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.009 сек.