Рекурсивное определение списка
Список может быть определён следующим образом: список либо пуст, либо состоит из элемента ссылающегося на список (в его ссылочном поле стоит указатель на другой список). Поскольку в этом определении понятие списка определено через само это понятие, то такое определение является рекурсивным. Таким образом, список можно назвать рекурсивной структурой данных. Проверим, является ли очередь из трёх элементов списком в смысле рекурсивного определения.
5
nil
Это было бы списком, если бы первый элемент (с информационным полем 5) ссылался на список. То есть нужно проверить, является ли списком следующая структура
5
3
nil
Это было бы списком, если бы первый элемент с информационным полем 3 ссылался на список. То есть нужно проверить, является ли списком следующая структура
nil
Но эта структура состоит из элемента, ссылающегося на пустой список (nil), а, следовательно, сама по определению является списком и, возвращаясь к исходной структуре, мы получаем, что созданная нами очередь является списком в смысле рекурсивного определения.
Для обработки рекурсивных структур данных естественно использовать рекурсивные процедуры и функции.
Рекурсивная процедура добавления к очереди нового элемента, значение которого берётся из текстового файла f1:
procedure add(var r : link);
begin
if r = nil then
begin new(r); r.next:=nil; read(f1, r.val) end
else add(r.next)
end;
Рекурсивная процедура выведения информационных полей очереди в текстовый файл f2:
procedure out(r : link);
begin
if r<> nil then begin write(f2, r.val:6); out(r.next) end
end;
Вызов этих рекурсивных процедур для создания и распечатки очереди может быть осуществлён в процедуре Button1Click следующим образом:
procedure TForm1.Button1Click(Sender: TObject);
begin
assignfile(f1, ' file8.txt '); assignfile(f2, ' file9.txt ');
reset(f1);
L:=nil;
while not eof(f1) do add(L);
closefile(f1);
rewrite(f2); out(L); closefile(f2);
end;
Как будет работать процедура out, если поменять местами оператор write(f2, r.val:6); и рекурсивный вызов out(r.next) ?
procedure out(r : link);
begin
if r<> nil then begin out(r.next); write(f2, r.val:6) end
end;
Оказывается, в этом случае элементы списка будут выводиться в обратном порядке, так как на входе в рекурсию будет осуществляться только рекурсивный вызов, а печать будет происходить на выходе из рекурсии, т.е. при движении от хвоста к голове списка.
Задача 25. Создать очередь из чисел файла file8.txt с помощью рекурсивной процедуры
procedure add(var r : link).
Описать рекурсивную функцию
function memb(r:link; b:integer) : boolean;
проверяющую, входит ли элемент с информационным полем b в список r. Описать рекурсивную процедуру
procedure dele(var r:link; w:integer);
удаляющую из списка r первое вхождение элемента с информационным полем w.
Используя функцию memb, проверить, входит ли число, введённое в поле Edit1, в созданный список. Если да, то удалить из списка первое вхождение этого числа с помощью процедуры dele и вывести преобразованный список в файл file9.txt с помощью процедуры out. В противном случае вывести сообщение: «Такого элемента нет».
Содержимое файла file8.txt: 9 -38 15 4 -21
15 9 -47 15 36
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
end;
type link = ^elem;
elem = record
