
- •Динамические структуры данных
- •Тип указателя на элемент динамической структуры данных может и должен быть описан перед
- •Пример. Создать односвязный список добавлением элементов в его начало
- •begin
- •Пример 2. Подсчитать число вхождений буквы 't' в заданное слово, завершающееся точкой.
- •Исключение элемента
- •кольцевыми
- •Пример. Пусть необходимо сформировать список следующего вида.
- •Ввод:
- •*СЛЕД
- •1) ADDEl(Val) - вставка
- •Результат
- •1.Исходное состояние
- •Добавление элемента очереди
- •стек
- •Создание и удаление стека из 10 элементов
- •BEGIN
- •Дек - это симбиоз стека и очереди.
- •бинарные

Динамические структуры данных
Марченко А.И., Марченко Л.А. Программирование в среде 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.