Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Алгоритмы и структуры данных.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
175.1 Кб
Скачать

Рекурсивные алгоритмы.

Рекурсивным называется объект, частично состоящий или определяемый с помощью самого себя. Подпрограмма называется рекурсивной, если она прямо или косвенно обращается к самой себе. В качестве примера рекурсивной функции рассмотрим вычисление факториала.

n! = n * (n – 1)!

(n – 1)! = (n – 1)(n – 2)!

(n – 2)! = (n – 2)(n – 3)!

………

2! = 2 * 1!

1! = 1 * 0!

0! = 1

function factor(i: integer): integer;

begin

if i > 0 then factor := i * factor(i – 1) else factor := 1;

end;

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

В практических приложениях необходимо убедиться, что максимальная глубина рекурсии не только конечна, но и достаточно мала.

Рекурсивные алгоритмы особенно подходят для задач, где обрабатываемые данные определяются в терминах рекурсии. Однако это не означает, что рекурсивное определение данных гарантирует эффективность использования рекурсивного алгоритма.

i := 0; f := 1;

while i < n do begin

i := i + 1;

f := i * f;

end;

fib(n) = n, если n = 0 или n = 1.

fib(n) = fib(n – 2) + fib(n – 1), если n >= 2.

function fib(n: integer): integer;

begin

if n = 0 then fib := 0 else if n = 1 then fib := 1

else fib := fib(n – 1) + fib(n – 2); end;

i := 1; j := 1; y := 0;

while i < n do begin

z := x; x := x + y;

y := z; i := i + 1;

end;

Следует избегать рекурсий там, где есть очевидные итерационные решения. Когда же циклический алгоритм усложняет программу, требует явной работы со стеком, лучше использовать рекурсию.

procedure quicksortR;

procedure sort(l, r: integer);

var i, j: integer; x, w: real;

begin

i := l; j := r; x := a[(l + r) div 2];

repeat

while a[i] < x do i := i + 1;

while x < a[j] do j := j – 1;

if i < j then begin w := a[i]; a[i] := a[j]; a[j] := w;

i := i + 1; j := j – 1; end;

until i > j;

if l < j then sort(i, j);

if i < r then sort(i, r);

end;

begin

sort(1, n);

end;

Структуры данных эвм.

Структура данных – это класс однородных математических объектов, ориентированных на эффективное представление данных в некотором классе задач подлежащих решению на ЭВМ

Самой простой структурой данных является простая переменная

Простая переменная – это структура которая состоит из одного элемента

Следующей структурой данных являются массивы

Служат для описания структур из множества элемента

При чем эти элементы упорядочены по индексу

Массивы – это пример композитной структуры (состоит из более простых структур)

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

Это те данные память под которые определяется в процессе работы программы. Наиболее распространненые:

Линейные циклические списки

Очереди

Стеки

Бинарные деревья

Элемент любой динмаической структуры состоит из двух частей

Информационной

И указателей (обеспечивают связь элементов друг с другом).

Реализация связанных списков.

Связанный список это динамическая структура данных (ДСД) с последовательным доступом, состоящая из отдельных узлов

Каждый узел содержит информационную часть и указатель на следующий элемент

Связанные списки бывают линейные (у них поле поле указателя последнего элемента содержит nil)

Циклические (у них поле указателя последнего элемента содержит ссылку на первый узел)

Однонаправленные (в таких списках каждый узел содержит ссылку только на следующий элемент списка)

Двунаправленные

Каждый узел списка удобно описывать типом запись

Type

Listelem= ; {определяет информационную часть элемента списка}

LIST=^Node;

Node=record`

Data:listelem;

Next:List;

End;

Var

Lst,p,q:list;

X:listelem;

Begin

New(lst);

Lst^.data:=x;

New(q);

Lst^.next:=q;

Q^.next:=nil;

Формирование линейного списка из n элементов.

New(lst);q:=lst;

P:=q;

For i:=1 to n do begin

New(q);

P^.next:=q;

P:=q

End;

P^.next:=nil;

Формирование списка с конца (экономия одной переменной).

P:=nil;

While n>0 do

Begin

New(q)

Q^.next:=n

P:=q;

N:=n-1;

End;

Функция, которая формирует список из элементов файла.

Type

Myfile=file of listelem;

Function newlist(var f:myfile):list;

Var

Lst,p,q:list;

X:listelem;

Begin

Reset(f);

New(lst);

P:=lst;

While not EOF(f) do

Begin

Read(f,x);

New(q);

q^.data:=x;

p^.next:=q;

p:=q;

end;

p^.next:=nil;

close(f);

newlist:=lst;

end;

Операции для работы с линейными списками.

для работы со списками необходимы следующие операции

включение- исключение элементов из списка

просмотр списка

Операция включения в список.

операция постановки элемента в список осуществляется гораздо проще чем для массивов поскольку нет необходимости что-либо перемещать

пусть P – указатель на элемент списка после которого нужно поместить новый элемент

new(q) {заказываем память под новый элемент}

q^.data:=x;

q^.next:=p^.next; {запись ссылки на следующий элемент списка}

p^.next:=q; {включение в список}

new(q)

q^.data:=p^.data

p^.data:=x

q^.next:=p^.next;

p^.next:=q;

Включение элемента в начало списка.

new(q);

q^.next:=lst;

lst:=q {новый указатель на список}

q^.data:=x;

Операция исключения из списка.

Q:=p^.next;

P^.next:=q^.next;

Dispose(q);

Удалить сам узел:

q := p^.next;

p^.data := q^.data;

p^.next := q^.next;

dispose(q);

Операция прохода по списку.

Доступ к элементу связанного списка осуществляется путем просмотра списка с самого начала

Предположим что над каждым элементом надо произвести некоторую операцию q(x)

Тогда так можно произвести проход по всему списку

P:=lst;

While p<>nil do begin

Q(p^);

P:=p^.next;

End;

Очень часто в списке необходимо найти элемент

Операция поиска в списке.

Пусть X это данные для поиска.

Найти элемент списка который хранит данные = X

While (p<>nil) and (p^.data<>x) do p:=p^.nextX

{после выхода из цикла p содержит ссылку на элемент содержащий x}

Процедура включения в список LST нового элемента x1 перед первым вхождением элемента x.

procedure place(LST: List; x, x1: LISTELEM);

var p, q: List;

eq: boolean;

begin

p := LST;

eq := false;

while (p <> nil) and not eq do

if p^.data = x then eq := true else p := p^.next;

if eq then begin

p^.data := x1;

new(q);

q^.data := x;

end;

q^.next := p^.next;

p^.next := q;

end;

Процедура удаления из непустого списка L последнего элемента.

Нужно два указателя: p и q. p используется для просмотра списка, а q указывает на предшествующий p элемент.

procedure deleteLast(L: List);

var p, q: List;

begin

q := L;

p := q^.next;

if p = nil then begin

writeln(‘Список пуст.’);

exit;

end;

while p^.next <> nil do begin

q := p;

p := p^.next;

end;

dispose(p);

q^.next := nil;

end;