Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции ТЭИС.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
11.22 Mб
Скачать

Реализация списков с помощью указателей

Реализация списков с помощью указателей освобождает от использования непрерывной области памяти для хранения списка. Это позволяет избавиться от перемещения элементов списка при вставке или удалении элементов. Однако ценой за это удобство становится дополнительная память для хранения указателей. Структура списка, реализованного с помощью указателей, представлена на рис.2.14. Список представлен записью LIST, состоящей из двух полей: last и elements. В поле last хранится число элементов списка, а в поле elements - указатель на первый элемент списка. Элемент списка хранится в записи, состоящей из двух полей: element и next. Поле element содержит значение элемента списка, а поле next - указатель на следующий элемент списка.

Реализация операторов INSERT и DELETE представлена блок-схемами на рис.2.15 и 2.16 соответственно. Реализация этих же операторов на языке Pascal представлена в листинге 2.5.

Листинг 2.5

type

position=integer;

ptrcell=^celltype;

celltype= record

element:elementtype;

next:ptrcell

end;

LIST = record

elements:^celltype;

last:position

end;

function Seek(p:position; L:LIST):ptrcell;

{Seek возвращает указатель в списке L на элемент с номером p (p=1,2,...,L.last}

var q:ptrcell; i:position;

begin

q:=L.elements; i:=1;

while i<>p do

begin

q:=q^.next; i:=i+1

end;

return(q);

end; {Seek}

procedure INSERT(x:elementtype; p:position; var L:LIST);

(INSERT вставляет элемент x в позицию p в списке L}

var

q,n:ptrcell;

begin

if (p>L.last+1) or (p<1) then error('Такой позиции не существует')

else

begin

q:=Seek(p,L); new(n); n^.element:=x; n^.next=q^.next; q^.next=n;

L.last:=L.last+1;

end

end; {INSERT}

procedure DELETE(p:position; var L:LIST);

{DELETE удаляет элемент в позиции p списка L}

var

q,qp:ptrcell;

begin

if (p>L.last) or (p<1) then error('Такой позиции не существует')

else

begin

if p=1 then

begin

q:=L.elements; L.elements:=q^.next

end

else

begin

qp:=Seek(p-1,L); q:=qp^.next; qp^.next:=q^.next;

end;

dispose(q); L.last:=L.last-1;

end

end; {DELETE}

Реализация списков с помощью курсоров

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

На рис. 2.17 показаны два списка M=a,b,c и L=d,e, вложенные в один массив SPACE длиной 10. Ячейки массива не занятые элементами списков образуют свободный список.

Реализация оператора INSERT списка, представленного с помощью указателей показана на рис.2.18. Реализация данного оператора на языке Pascal показана в листинге 2.6.

Реализацию остальных операторов списка сделайте самостоятельно.

Листинг 2.6

const

maxlen=100; { или другое подходящее число }

type

position=integer;

celltype= record

element:elementtype;

next:position

end;

LIST = record.

elements:position;

last:position

end;

var

SPACE=array[1..maxlength] of celltype;

free:position; {курсор, указывающий на свободный элемент}

function Seek(p:position; L:LIST):position;

{Seek возвращает курсор в списке L на элемент с номером p=1,2,...,L.last}

var q, i:position;

begin

q:=L.elements;

i:=1;

while i<>p do

begin

q:=SPACE[q].next; i:=i+1

end;

return(q);

end; {Seek}

procedure INSERT(x:elementtype; p:position; var L:LIST);

(INSERT вставляет элемент x в позицию p в списке L}

var

q,n:position; i:position;

begin

if L.last>=maxlen then error('Список полон')

else if (p>L.last+1) or (p<1) then error('Такой позиции не существует')

else

begin

q:=Seek(p,L);

n:=free; free:=SPACE[n].next; {Эти два оператора заменяют new(n)}

SPACE[n].element:=x; SPACE[n].next=SPACE[q].next; SPACE[q].next=n;

L.last:=L.last+1;

end

end; {INSERT}