Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
algoritmy.docx
Скачиваний:
15
Добавлен:
27.09.2019
Размер:
237.74 Кб
Скачать

5. Анализ рекурсивных алгоритмов. Анализ вставки элемента в бинарное дерево поиска.

5.Анализ сложности рекурсивных алгоритмов

Одним из основных методов построения рекурсивных алгоритмов является метод декомпозиции. Идея метода состоит в разделении задачи на части меньшей размерности, получении решений для выделенных частей и объединении решений при возврате рекурсивных вызовов. Если в алгоритме происходит разделение задачи на b подзадач, которое приводит к необходимости решения а подзадач размерностью п/Ь, то функцию трудоемкости (см. [3]) можно представить в виде FA (n)=aF A (n/b) + d(n) + U (п),где d(n) — трудоемкость алгоритма деления задачи на подзадачи, U(n) — трудоемкость алгоритма объединения полученных решений.Рассмотрим, например, известный алгоритм сортировки слиянием, принадлежащий Дж. Фон Нейману (см. 3.6. основного текста). На каждом рекурсивном вызове переданный массив делится пополам, что дает оценку для d(n) — 0(1), далее рекурсивно вызывается сортировка полученных массивов половинной длины (до тех пор,пока длина массива не станет равной единице), и возвращенные отсортированные массивы объединяются с трудоемкостью 0(п). Тогда ожидаемая трудоемкость на сортировку составит: FА (п) = 2 •FA(п/2) + 0 (1) + 0 (п). Тем самым возникает вопрос о получении оценки сложности функции трудоемкости, заданной в виде (Д.2.4), для произвольных целых значений а и Ь. Ответ на этот вопрос можно получить на основе теоремы о рекуррентных соотношениях, авторами которой являются Дж. Бентли, Д.Хакен и Дж. Сакс (статья 1980 г.), приведем ее формулировку в соответствии с [3]. Теорема Д.2.1. Пусть а > 1, b > 1 — константы, д(п) — функция, пусть далее

/ (п) = а • f (n/b) + д (п), где п/Ь = [п/Ъ] или п/Ь — [п/Ь], тогда

(1) Если д(п) = О (n^ log b (a-£)), £ > 0, то f(п) = 0 (n log b (a) ).

Пример: / (п) = 8 • f (га/2) + п 2 , тогда / (п) = 0 (п 3 ).

(2) Если g(n)=Q (n^ log b a ), то / (n) = 0 (n^ log b a • log n).

Пример: / (n) = 2 • / (n/2) + 0 (n), тогда / (n) = 0 (n • logn).

(3) Если д (n) = 0 (n ^log b a+£ ) , e > 0, то / (n) = 0 (g (n)).

Пример: / (n) = 2 • / (n/2) + n 2 , здесь подходит случай (3), поскольку

n^log b a = П ^1 , И ; следовательно / (п) = 0 (п ^2 ).

Данная теорема является мощным средством анализа асимптотической сложности рекурсивных алгоритмов, использующих метод декомпозиции, но, к сожалению,она не дает возможности получить в явном виде коэффициенты функции трудоемкости. Для решения этой задачи необходим более детальный анализ рекурсивного дерева.На основании этой теоремы получим оценку сложности функции трудоемкости для алгоритма сортировки слиянием. Поскольку в этом случае д (п) — 0 (n :log2 2 ),то /д (п) = 0 (п • logn).

Анализ вставки элемента в бинарное дерево поиска.

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

Вставка

Для вставки нового значения v в бинарное дерево поиска Т мы воспользуемся процедурой Tree_Insert. Процедура получает в качестве параметра узел z, у которого key [z] = v, left [z] = NIL и right [z] = NIL, после чего она таким образом изменяет Т и некоторые поля z, что z оказывается вставленным в соответствующую позицию в дереве.

TreeJnsert(T, z)

1 у *- NIL

2 х *- root[T]

3 while x ф nil

4 do у <— x

5 if key[z] < key[x]

6 then x <— left[x]

7 else x <— right[x]

8 p[z]<r-y

9 if у = NIL

10 then root[T] <— z > Дерево Г — пустое

11 else if key[z] < key[y]

12 then left[y] <- z

13 else right[y] <— z

На рис. 12.3 показана работа процедуры Tree_Insert. Подобно процедурам Tree_Search и Iterative_Tree_Search, процедура TreeInsert начинает работу с корневого узла дерева и проходит по нисходящему пути. Указатель х отмечает проходимый путь, а указатель у указывает на родительский по отношению к х деревья поиска 325

Рис. 12.3. Вставка элемента с ключом 13 в бинарное дерево поиска. Светлые узлы указывают путь от корня к позиции вставки; пунктиром указана связь, добавляемая при вставке нового элемента узел. После инициализации цикл while в строках 3-7 перемещает эти указатели вниз по дереву, перемещаясь влево или вправо в зависимости от результата сравнения ключей key [x] и key [z)9 до тех пор пока х не станет равным NIL. Это значение находится именно в той позиции, куда следует поместить элемент z. В строках 8-13 выполняется установка значений указателей для вставки z. Так же, как и другие примитивные операции над бинарным деревом поиска, процедура Tree_Insert выполняется за время О (h) в дереве высотой h.

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