Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Itogovye_otvety_programmirovanie_1.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
202.75 Кб
Скачать

16. Связанные списки

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

type Т = record key: integer;

next: ^T end

Список элементов типа Т показан на рис. Ссылка head указывает на первую компоненту списка.

Динамическими объектами здесь являются записи типа Point с полями, содержащими атрибуты необходимых объектов (н-р, точек; их м.б. произвольное кол-во, их можно объединить в ломаную, перерисовать и т.д.). Первоначально список пуст, указатель head установлен в nil.

type link=^point; point=record x,y: integer; color,mask: byte; next: link end; var head,p: link; begin head:=nil; p:=new(link); p^.x:=xmouse; p^.y:=ymouse; p^.color:=curcolor; p^.mark:=curmt; p^.next:=head; head:=p;…end.

Последние два оператора годятся для вставки очередного элемента в список. Первым в списке будет элемент, вставленный последним.

17. Связанные списки. Создание очередного элемента. Просмотр списка

См. 16 вопрос +

Н-р, перерисовать маркеры другим цветом.

var cur: link; begin cur:= head; while cur<>nil do begin drawmarker(cur^.x, cur^.y, cur^.color, cur^.type); cur:=cur^.next end; end.

Первым будет рисоваться маркер, созданный последним, т.к. связанный список соответствует структуре LIFO.

18. Добавление компонент в середину списка

Совсем не трудно вставить компоненту (NPoint) в середину списка, когда имеется ссылка на компоненту, предшествующую данной в реорганизованном списке. Назовём её OPoint.

NPoint^.next := OPoint^.next;

OPoint^next := NPoint;

Эти операторы будут правильно работать и в том случае, если OPoint – последняя компонента в списке, т.е. OPoint^.next = nil. Если OPoint = nil, то выполнение этих операторов приводит к ошибке.

procedure InsertAfter (OPoint, NPoint: link);

begin NPoint^.next := OPoint^.next;

OPoint^next := NPoint end;

Труднее организовать процедуру InsertBefore, т.к. тогда новую компоненту надо вставлять перед компонентой, на которую у неё есть ссылка.

procedure InsertBefore (OPoint, NPoint: link; var head: link);

var cur: link;

begin If OPoint = head then begin

NPoint^.next := head;

head := NPoint; end

else begin

cur := head;

while cur^.next<>OPoint do cur := cor^.next;

cur^.next := NPoint;

NPoint^next := OPoint end;

end;

Имеется ещё один способ реализации процедуры InsertBefore. Им пользуются тогда, когда кол-во информации, содержащейся в компонентах списка не очень велико, а список достаточно длинный. Сначала новая компонента с помощью процедуры InsertAfter помещается в список, но попадает не на своё место, а затем меняется местами содержимое компонент.

procedure InsertBefore2 (OPoint, NPoint: link);

var temp:Point; begin NPoint^.next:=OPoint^.next; OPoint^.next:=NPoint; temp:=OPoint^; OPoint^:=NPoint^; NPoint^:= temp; end;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]