Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2011_12 Комп.Науки_2сем.doc
Скачиваний:
4
Добавлен:
13.09.2019
Размер:
476.67 Кб
Скачать

19.8.Примеры рекурсивных программ

19.8.1.Вывод цифр целого числа в прямом порядке

procedure Print(x: integer);

begin

if x > 9 then Print(x div 10); //Рекурсивный вызов для числа x без младшей цифры

write(x mod 10 :3) //Вывод младшей цифры на рекурсивном возврате

end;

Цифры легче получать с конца числа. Поэтому на рекурсивном спуске мы путем деления на 10 получаем последовательность чисел, которые заканчиваются очередной цифрой с конца числа. На рекурсивном возврате мы эту младшую цифру получим как остаток от деления на 10 и выведем.

Пусть x=1234, тогда на рекурсивном спуске будут происходить следующие вызовы процедуры Print:

Print(1234); Print(123); Print(12); Print(1);

Рекурсивный спуск закончился, последний экземпляр Print выведет цифру 1.

На рекурсивном возврате Print(12) выведет цифру 2, Print(123) – цифру 3, Print(1234)‑ цифру 4.

В результате получим последовательность цифр: 1 2 3 4

19.8.2.Поиск максимального элемента массива

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

Больше рекурсивных вызовов не происходит, начинается завершение работы вызванных функций, т.е. рекурсивный возврат. На каждом шаге рекурсивного возврата к уже обработанной части массива добавляется один элемент. Если этот элемент A[L] больше найденного ранее максимума, то значение A[L] принимается за новое значение максимума.

const N=10;

type vector=array[1..N] of integer;

var V:vector; max:integer;

function RMax(const A:vector; L:integer):integer;

{ L – длина части массива, рассматриваемой на каждом шаге рекурсии.}

var M: integer;

begin

if L=1 then RMax:=A[1] //Считаем A[1] максимальным; рекурсивный спуск закончен

else begin

M:=RMax(A, L-1); //Уменьшение длины части массива на 1 на рекурсивном спуске

if A[L]>M then RMax:=A[L] //Сравнение на рекурсивном возврате

end

end;

begin ... max:=RMax(V, N); ...

end.

19.8.3.Быстрая сортировка – усовершенствованный метод сортировки обменом

Алгоритм быстрой сортировки, который разработал англичанин Чарльз Хоор (C. Hoare) в 1960 г., является наиболее популярным алгоритмом сортировки.

Анализ эффективности быстрой сортировки

В среднем число операций порядка Nlog2N, остальные сортировки в среднем N2 операций.

Преимущество быстрой сортировки проявляется при больших N. Она сортирует массив с элементами в обратном порядке практически с такой же скоростью, как уже отсортированный массив.

Принцип быстрой сортировки

Причина неэффективности метода сортировки обменом (метод «пузырька») в том, что меняются местами два соседних элемента, если для них нарушена упорядоченность. Менять местами надо максимально удаленные элементы.

Алгоритм одного шага быстрой сортировки

  1. Положить i=1, j=N

  2. Выбрать в массиве случайным образом элемент x.

  3. Повторять

Просматривая массив слева направо, найти элемент Ai>x.

Просматривая массив справа налево, найти элемент Aj<x.

Если i<=j, то поменять местами Ai и Aj, увеличить i+1, уменьшить j-1

Пример одного шага быстрой сортировки

Для сортировки массива надо то же самое проделать с обеими частями (слева и справа от x), затем с частями этих частей и т.д. до тех пор, пока каждая часть не будет содержать только один элемент. Получили рекурсивный алгоритм.

procedure QSort(L,R:integer); //L, R – индексы самого левого и самого правого элементов подмассива

var i,j,x,w:integer;

begin

i:=L; j:=R;

x:=A[(L+R) div 2]; //x - средний элемент

repeat

while A[i]<x do i:=i+1; //Просмотр слева направо

while A[j]<x do j:=j-1; //Просмотр справа налево

if i<=j then

begin //Перестановка A[i] и A[j]

w:=A[i];

A[i]:=A[j];

A[j]:=w;

i:=i+1; j:=j-1

end

until i>j;

if L<j then QSort(L,j); //Рекурсивный вызов для левой половины массива

if i < R then QSort(i,R) //Рекурсивный вызов для правой половины массива

end;

begin Sort(1,N); . . .

end.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]