Для того щоб видалити вузол, необхідно скоригувати значення покажчика вузла, який знаходиться перед видаляється вузлом (рис. 8.12).
Рис. 8.12. Видалення елемента зі списку
Оскільки вузол є динамічної змінної, то після виключення вузла зі списку він займає пам’ять повинна бути звільнена. Звільнення динамічної пам’яті, або, як іноді кажуть,”знищення змінної” виконується викликом процедури dispose. У процедури dispose один параметр – покажчик на динамічну змінну. пам’ять, займана цією динамічноїзмінної, повинна бути звільнена. наприклад, в програмі
var р: ^ Integer; begin new (p); {Інструкції програми} dispose (p); end
створюється динамічна змінна р, а потім вона знищується. Звільнилася пам’ять зможуть використовувати інші змінні. Якщо цього не зробити, то, можливо, через нестачу вільної пам’яті в якийсь момент часу програма не зможе створити чергову динамічну змінну.
Наступна програма дозволяє додавати і видаляти вузли впорядкованого списку. Діалогове вікно програми наведено на рис. 8.13.
Процедури додавання вузла в список і виведення списку, а також оголошення типу вузла списку нічим не відрізняються від відповідних процедур рас смотреніі раніше програми Упорядкований динамічний список 2, тому вони тут не наводяться.
Видалення вузла зі списку виконує процедура TForm1.Button3Click, яка запускається натисканням кнопки Видалити (Buttons). Текст процедури приведений в лістингу 8.6.
Рис. 8.13. Вікно програми Динамічний список
Лістинг 8.6. Видалення вузла зі списку
unit dlist2 _; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class (TForm) Label1: TLabel; Label2: TLabel; Button1: TButton; Button2: TButton; Label3: TLabel; Edit1: TEdit; Edit2: TEdit; procedure Button1Click (Sender: TObject); procedure Button2Click (Sender: TObject); procedure FormActivate (Sender: TObject); private {Private declarations} public {Public declarations} end; var Form1: TForm1; implementation {$ R * .DFM} type TPStudent = ^ TStudent; // покажчик на тип TStudent TStudent = record f_name: string [20]; // прізвище l_name: string [20]; // ім'я next: TPStudent; // наступний елемент списку end; var head: TPStudent; // початок (голова) списку procedure TForm1.Button1Click (Sender: TObject); var node: TPStudent; // новий вузол списку curr: TPStudent; // поточний вузол списку pre: TPStudent; // попередній, щодо curr, вузол begin new (node); // створення нового елемента списку node ^ .f_name: = Edit1.Text; // прізвище node ^ .l_name: = Edit2.Text; // ім'я // додавання вузла в список // спочатку знайдемо підходяще місце в списку для вузла curr: = head; pre: = NIL; {Увага! якщо наведене нижче умова замінити на (node.f_name > curr ^ .f_name) and (curr <> NIL) то при додаванні першого вузла виникає помилка часу виконання, так як curr = NIL і, отже, змінної curr. ^ name немає! У використовуваному варіанті умови помилка не виникає, так як спочатку перевіряється умова (curr <> NIL), значення якого FALSE і друга умова в цьому випадку не перевіряється. } while (curr<> NIL) and (node.f_name > curr ^ .f_name) do begin // введене значення більше поточного pre: = curr; curr: = curr ^ .next; // до наступного вузла end; if pre = NIL then begin // новий вузол в початок списку node ^ .next: = head; head: = node; end else begin // новий вузол після pre, перед curr node ^ .next: = pre ^ .next; pre ^ .next: = node; end; Edit1.text: = ''; Edit2.text: = ''; Edit1.SetFocus; end; procedure TForm1.Button2Click (Sender: TObject); var curr: TPStudent; // поточний елемент списку n: integer; // довжина (к-ть елементів) списку st: string; // строкове представлення списку begin n: = 0; st: = ''; curr: = head; while curr <> NIL do begin n: = n + 1; st: = st + curr ^ .f_name + '' + curr ^ .l_name + # 13; curr: = curr ^ .next; end; if n <> 0 then ShowMessage ( 'Список:' + # 13 + st) else ShowMessage ( 'У списку немає елементів.'); end; procedure TForm1.FormActivate (Sender: TObject); begin head: = NIL; end; end.
Процедура переглядає список від початку, порівнюючи вміст полів поточного вузла з вмістом полів введення діалогового вікна. Якщо їх вміст збігається, то процедура просить користувача підтвердити видалення вузла. Якщо користувач натисканням кнопки ОК підтверджує, що вузол повинен бути вилучений, то процедура видаляє його. Якщо вузла, який хоче видалити користувач, у списку немає, програма виводить повідомлення про помилку.