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

Динамические структуры данных

Марченко А.И., Марченко Л.А. Программирование в среде Turbo PASCAL. Базовый курс 7.0. – К.:ВЕК+,1999. – 464 с.

Связанные динамические данные. Списки

Ссылочная переменная - указатель

В простейшем случае элемент динамической структуры данных

должен состоять из двух полей: информационного и указательного.

 

 

 

 

Type

 

 

 

 

 

Tptr=^Telem; {ссылка на динамическую

info

info

info

 

Telem = Record

переменную}

 

 

 

 

 

 

 

 

info:integer;

 

 

 

 

 

 

*next

*next

*next

 

next: Tptr;

{указатель}

 

 

 

 

end;

1

 

 

 

 

 

Тип указателя на элемент динамической структуры данных может и должен быть описан перед описанием типа этого элемента.

цепочкой линейным однонаправленным или односвязным списком.

info next

Info next

info next

info nil

р

 

 

Линейные списки – это данные динамической структуры, которые представляют собой совокупность линейно-связанных однородных элементов, для которых разрешены следующие действия:

1)добавление элемента в начало;

2)добавление элемента в конец (хвост) списка (частный случай вставки);

3)вставка элемента между двумя любыми другими элементами;

4)исключение элемента (удаление любого, как крайнего, так и

среднего элемента списка).

 

2

 

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

р

 

 

key

*next

 

 

key

*next

 

q

 

 

nil

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

начало

{spis0b.pas + с адресами}

Program spis0b;

Type sv = ^struct; Struct = record

key: integer; {ключевое поле}

next: sv

{указатель на следующий элемент}

end;

 

Var

 

p, t, q: sv;

 

x: integer;

 

BEGIN

{ указатель на начало пуст}

p := nil;

q := nil;

{ указатель на конец пуст}

writeln('Введите элемент (Число больше 999 - признак конца)');

read(x); {ввод первого элемента} while x<=999 do

3

begin

 

 

 

 

 

 

 

new(t);

 

{ создание нового элемента списка, t - текущее

указателя }

 

 

 

 

 

значение

 

 

 

 

 

 

 

 

t^.key:=x;

 

 

 

{заполнение ключевого поля}

if (p=nil) then q:=t; {если это первый элемент, то он же и

 

 

 

 

последний (признак конца)}

 

t^.next:=p;

writeln(' ', longint(t^.next));

 

{ вывод адреса}

p:=t;

 

{ writeln(ptr(сегмент,смещение)); p-через Wath }

read(x) ;

 

 

{ввод очередного элемента}

 

end;

 

 

{ writeln(' ', seg(t^.next),'+',ofs(t^.next));}

 

writeln('элемент - адрес');

 

 

 

while t<>nil{не пусто} do

 

 

 

begin

{ofs() возвращает смещение адреса объекта типа WORD}

writeln(t^.key:6,' / ', longint(t^.next));

 

 

 

t:=t^.next;

{ \ нельзя печатать сам указатель}

 

end;

 

 

 

 

 

 

 

END.

 

 

Результаты:

8

147554 3048

 

 

 

 

 

 

 

 

 

 

6

147554 3040

 

 

 

 

 

 

4

1475 477512

 

 

 

 

 

 

2

1475477 504

 

 

 

 

 

 

1

0

4

Пример 2. Подсчитать число вхождений буквы 't' в заданное слово, завершающееся точкой.

Program spis1atp;

{spis1a.pas +}

Type sv {связь}= ^zv; {звено строки}

Zv = record

 

info: char; {Информационное поле}

next: sv

{Указатель на следующий элемент}

end;

 

Var

 

P {Ук-ль на начало}, t {Указатель на текущее звено}: sv;

sym: char;

 

k: integer;

 

BEGIN

{Формирование заглавного звена}

new(p); t:=p;

p^.next:=nil; {резервирование памяти}

read(sym);

{Чтение первого символа}

Write('Введи остальные символы и точку ');

while sym<>'.' do

{Цикл обработки последовательных

литер строки}

 

begin

 

5

new(t^.next); t:=t^.next;

{адрес следующего}

t^.info:=sym; t^.next:=nil;

 

read(sym)

 

end; {Исходное слово представлено в виде цепочки}

k:=0;

 

t:=p;

{Подсчет}

while t<>nil do

 

begin

 

t:=t^.next ;

{}

if t^.info='t' then k:=K+1; end;

Writeln;

Writeln('Буква t входит в слово ',k,' раз'); END.

6

Исключение элемента

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*

 

 

*

 

 

 

*

 

*

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

key

next

Для вставки элемента:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*

 

 

 

 

 

 

 

 

*

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*

 

 

 

 

 

 

 

 

 

 

*

 

 

 

 

*

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

До занесения

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Занесение

 

 

 

 

 

 

 

 

 

 

*

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*

 

 

 

 

 

 

 

*

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Список - это набор динамических элементов (чаще всего переменных

типа «запись»), связанных между собой каким-либо способом. Списки бывают линейными и кольцевыми, односвязными и двусвязными, нелинейными и т.д.

nil

 

info

info

 

info

info

 

 

 

р

* next

* next

* next q

nil

 

 

 

 

 

7

кольцевыми

Кольцевые списки – это такие t данные, как и линейные списки, но имеющие дополнительную связь между последним и первым элементами списка.

p

info

info

info

info

* next

* next

* next

nil

 

 

 

 

key

*next

 

 

key

*next

 

 

 

key

*next

p

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Линейный двусвязный (двунаправленный)

nil

 

*пред

 

*пред

 

 

 

 

 

 

элем 1

 

элем 2

 

элем К

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*след

 

*след

 

 

nil

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

nil

 

 

*пред

*пред

*пред

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

элем 1

 

элем 2

элем К

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

*след

 

 

*след

*след

 

nil

 

 

 

 

 

 

 

 

 

 

 

 

 

8

 

*пред

р*

*след

 

*пред

 

*пред

*пред

элем 1

 

элем 2

элем К

 

 

*след

 

*след

 

*след

 

 

 

 

 

 

 

 

 

 

 

 

nil

 

 

*пред

*пред

*пред

 

 

 

 

 

 

 

 

 

 

 

 

 

р*

 

 

 

элем 1

 

элем 2

элем К

 

 

 

 

 

 

 

 

 

 

*след

 

*след

 

*след

 

*след

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Вставка

*пред

*пред

*след

9

Пример. Пусть необходимо сформировать список следующего вида.

 

nil

*left

р

key

key

*rignt

* rignt

 

* left

*left

*left

key

key

key

*rignt

 

* rignt

nil

{Создание двусвязного списка добавлением элементов в начало (конец)

списка}

 

 

 

 

 

 

nil

Ввели 1 элемент

Program spis2а;

{вывод не верен}

 

p=t

x1

Type sv = ^struct;

 

struct = record

q=t

nil

 

key: integer;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

nil

 

left

left: sv ; {на предыдущий}

 

 

 

right: sv { на следующий}

p

 

x1

 

x2

end;

 

 

 

 

 

 

 

Ввели 2 элемент

 

rignt

 

nil

Var p,t,q: sv;

 

 

 

 

 

 

 

 

 

x: integer;

 

 

 

 

 

 

 

BEGIN

p:=nil; q:=nil;

writeln('Введите элемент (Число >999-признак конца)'); read(x);

10

while x<=999 do

 

begin

 

new(t);

{новый элемент списка}

t^.key:=x;

{заполнение ключевого списка}

t^.right:=nil;

{это последний элемент, т.к. добавление в конец}

t^.left:=q; {привязывание нового элемента справа(с предыдущим) дадим ему значение признака конца}

writeln(longint(t^.right),' / ',t^.key:6,' \ ', longint(t^.left)); { dispose(t);}

if (p=nil) then p:=t {текущему 1 раз}

else q^.right:=t; {указатель текущем в правое поле}

q :=t; {установка указателя на текущий элемент (последний)}

read(x); end;

writeln('на левый - элемент - на правый(сегмент + смещение)'); t:=q;

while t<>nil{не пусто} do begin

writeln(longint(t^.right),' / ',t^.key:6,' / ', longint(t^.left)); { dispose(t);}t:=t^.left;

end

 

11

 

END.

Соседние файлы в папке 2семестр