- •Лабораторна робота № 12.
- •4. Короткі теоретичні відомості.
- •4.1. Статичні і динамічні змінні
- •4.2. Посилання і покажчики
- •4.3. Лінійний (одно направлений) список
- •4.3.1. Створення і проглядання списку
- •4.3.2. Створення списку цілих чисел впорядкованих за збільшенням
- •4.3.3. Видалення елемента із списку
- •4.4. Двох зв'язаний список - кільце
- •4.5. Стек
- •4.6. Черга
- •5. Варіанти завдань
4.3.2. Створення списку цілих чисел впорядкованих за збільшенням
Після введення чергового числа з клавіатури визначаємо його місце в списку. Помітимо, що при цьому елемент може бути вставлений або в початок списку, або в кінець його, або у всередину. Перший і другий випадки розглянуті вище. Зупинимося на третьому випадку.
Для того, щоб вставити в список елемент із значенням d між двома елементами, потрібно знайти ці елементи і запам'ятати їх адреси (перша адреса — в змінній pred, другий — в posl), після чого встановити нові зв'язки із змінною, в якій зберігається значення d.
Графічно це можна представити так:
pred posl
|
|
|
|
|
|
|
|
|
|
|
|
sl
-
d
Program p4; { Створення відсортованого списку }
type ptr = ^s;
s = record
data:integer;
next:ptr; end;
var d : integer; {значення інформаційної частини елемента списку}
u : ptr; {глобальна змінна u ‑ адреса першого елемента списку }
procedure print(first:ptr);
begin
while first<>nil do
begin
write(first^.data,' ');
first:=first^.next;
end;
end;
procedure insElem (d:integer; var u:ptr);
{ вставка заданого елемента в список }
var pred,posl,sl : ptr;
begin
new(sl); sl^.data:=d; sl^.next:=nil;
if u=nil
then u:=sl {Якщо список порожній, то вставляється перший елемент }
else {Якщо список не порожній, то проглядаємо його до тих пір, поки не}
begin { відшукається відповідне місце для sl^ або не закінчиться список }
pred:=u; posl:=u;
while (posl<>nil) and (posl^.data<=d) do
begin pred:=posl; posl:=posl^.next; end;
if posl=nil { Пройдений весь список }
then pred^.next:=sl {Елемент додається в кінець списку}
else {Пройдений не весь список }
begin
sl^.next := posl;
if posl=u
then u:=sl {Вставляємо в початок списку}
else pred^.next:=sl; {Вставляємо всередину списку}
end;
end;
end;
Begin
u:=nil; { Список порожній }
writeln(' Bведите елемент. Закінчення введення 0'); read(d);
while d<>0 do begin insElem(d,u); read(d); end;
writeln; write('Сnucoк: ');
print(u); { Вивід списку }
End.
4.3.3. Видалення елемента із списку
Приклад 2. Видалити із заданого списку всі входження елемента із заданим значенням інформаційної частини.
Позначимо u — початковий список, d — значення інформаційної частини елемента, що видаляється. Видалити елемент можна з будь-якого місця списку. Видалення елемента з початку списку.
Графічно можна зобразити так:
sl
u
-
nil
3
5
1
9
Напишемо фрагмент програми:
sl := u; {Запам'ятаємо адресу першого елемента списку}
u:= u^ .next; { тепер u указує на другий елемент списку}
dispose(sl); {Звільнимо пам'ять, зайняту змінної sl^ }
Видалення елемента з середини списку
Для цього потрібно знати адреси елемента і елемента, що знаходиться в списку перед ним, що видаляється.
sl := u; {змінна sl для зберігання адреси елемента, що видаляється}
Знайдемо адреси потрібних елементів списку
while (sl <> nil) and (sl^.data <> d) do
begin
pred := sl;
sl := sl^.next
end;
dispose(sl)
Графічно це можна зобразити таким чином:
pred sl
u
-
…
…
…
3
Видалення елемента з кінця списку
Воно проводиться, коли покажчик pred показує на передостанній елемент списку, а sl — на останній. Знайдемо передостанній елемент.
sl:=u;
pred:=u;
while sl^.next <> nil do
begin
pred:= sl;
sl:= sl^.next;
end;
Видаляємо елемент sl^ із списку і звільняємо займану їм пам'ять.
pred ^.next:= nil;
dispose(sl);
pred sl
u
-
…
…
nil
nil
Отже, тепер ми готові записати в остаточному вигляді програму для створення, друку і видалення елементів відсортованого лінійного списку.
Program p5;{Створення, друк і видалення елементів відсортованого списку}
{$i WrHexW.pas} {Директива включення в компіляцію з поточного каталогу файлуWrHexW.pas}
type ptr = ^s;
s = record data:integer; next:ptr; end;
var d : integer; u : ptr;
procedure print(first:ptr); {печать списка}
begin
while first<>nil do
begin write(first^.data,' '); first:=first^.next; end;
writeln;
end;
procedure Init(var u:ptr); {создание списка}
var pred,posl,sl : ptr;
begin
writeln (' ':10,' Створення лінійного відсортованого списку');
writeln('за збільшенням інформаційної складової елемента'); writeln;
writeln (' Bведите елемент списку: число типу integer. Закінчення введення: 0');
u:=nil; {список пуст} read(d);
while d<>0 do begin
new(sl); sl^.data:=d; sl^.next:=nil;
if u=nil
then u:=sl { Якщо список порожній, то вставляється перший елемент }
else { Якщо список не порожній, то проглядаємо його до тих пір, поки не }
begin { відшукається відповідне місце для sl^ або не закінчиться список }
pred:=u; posl:=u;
while (posl<>nil) and (posl^.data<=d) do
begin pred:=posl; posl:=posl^.next; end;
if posl=nil { }
then pred^.next:=sl {Пройдений весь список. Елемент додається в кінець}
else begin { Пройдений не весь список }
sl^.next := posl;
if posl=u
then u:=sl { Вставляємо в початок списку }
else pred^.next:=sl; { Вставляємо всередину списку }
end;
end;
read(d);
end;
end;
procedure del(d:integer;var u:ptr); {Видалення елементів із значенням d}
var sl, pred: ptr;
begin
sl:=u; { Змінна sl для зберігання адреси елемента, що видаляється }
while sl<>nil do {Проглядання всього списку і пошук адрес потрібних елементів }
if sl^.data=d
then begin
if sl=u
then begin { Видалення елемента з початку списку.}
u:=u^.next; { Тепер u указує на другий елемент списку }
dispose(sl); { Звільнимо пам'ять, зайняту змінній sl^ }
sl:=u { Тепер sl указує на другий елемент списку }
end
else begin { Видалення елемента з середини і кінця списку }
pred^.next:=sl^.next;
dispose(sl);
sl:=pred^.next;
end;
end
else begin { Збереження адрес попереднього і подальшого елементів }
Задание:
Для самоконтроля усвоения рассмотренного
материала прорисуйте
изменение значений элементов списка
и переменных: u,
sl,
pred
и
posl
sl:=sl^.next;
end;
end;{----------------}
Begin
init(u); { Формування списку }
print(u); { Вивід списку }
write(' ':17,'u --> ');WrHexW(seg(u));write(':');WrHexW(ofs(u));writeLn;
write(' ':17,'u^ -> '); WrHexW(seg(u^)); write(':');WrHexW(ofs(u^));
write(' ','u^.next^ --> '); WrHexW(seg(u^.next^)); write(':');
WrHexW(ofs(u^.next^)); writeLn;
write('Bведите число: '); readln(d);
del(d,u); { Видалення елемента списку }
print(u); { Вивід списку }
write(' ':17,'u^ -> '); WrHexW(seg(u^)); write(':');WrHexW(ofs(u^));
write(' ','u^.next^ --> '); WrHexW(seg(u^.next^)); write(':');
WrHexW(ofs(u^.next^));
End.
{ Протокол роботи програми
Створення лінійного відсортованого списку
за збільшенням інформаційної складової елемента
Введіть елемент списку: число типу integer. Закінчення введення: 0
90
10
50
77
0
10 50 77 90
u ---> 2081:0064
u^ --> 24AE:0008 u^.next^ --> 24AF:0000
Bведите число: 10
50 77 90
u^ --> 24AF:0000 u^.next^ --> 24AF:0008 }