- •Основные понятия структур
- •Концепция типа данных, простейшие типы данных, стандартные типы данных, органические типы (диапазоны)
- •Статические и полустатические структуры данных
- •2. 1. Массив.
- •2. 2. Запись, записи с вариантами.
- •2. 3. Стек.
- •5. Очередь
- •2. 7. Отображение
- •Динамические структуры данных
- •3.1. Односвязные списки, кольцевой список
- •3. 2. Двусвязный список, кольцевой двусвязный список
- •4. Рекурсивные алгоритмы
- •4. 1. Деревья, бинарные деревья, представление деревьев
- •4. 2. Основные операторы, используемые для работы с деревьями
- •4. 3. Алгоритм создания дерева бинарного поиска
- •4. 4. Прохождение бинарных деревьев
- •1. Прохождение в прямом порядке
- •3. Прохождение в обратном порядке
- •4. 5. Когда рекурсию использовать не нужно
- •4. 6. Рекурсивные программы, примеры
- •5. Поиск
- •5. 1. Линейный поиск
- •5. 2. Двоичный поиск
- •5. 3. Индексно-последовательный поиск
- •5. 3. Поиск в таблице
- •5. 4. Поиск прямой строки
- •Поиск по бинарному дереву
- •Алгоритм кнута, Морриса и Пратта
- •5. 6. Алгоритм Боуера и Мура
- •Сортировка. Необходимые определения и классификация сортировок. Сортировки прямого включения и выбора. Их эффективность Необходимые определения и классификация сортировок.
- •Сортировка методом прямого включения
- •Эффективность алгоритма сортировки прямого включения
- •Сортировка методом прямого выбора
- •Эффективность алгоритма сортировки прямого выбора
- •Сортировка прямого обмена. Её эффективность
- •Эффективность алгоритма сортировки прямого обмена
- •Улучшенные методы сортировки. Быстрая сортировка. Её эффективность.
- •Быстрая сортировка
- •Принцип работы быстрой сортировки
- •Пример работы быстрой сортировки
- •Блок-схема быстрой сортировки
- •Улучшенные методы сортировки. Сортировка шелла. Её эффективность. Сортировка шелла
- •Принцип работы сортировки шелла и необходимые расчёты для её реализации
- •Пример расчёта последовательности расстояний для малых массивов
- •Пример работы сортировки шелла
- •Принцип работы пирамидальной сортировки
- •Пример работы пирамидальной сортировки
- •Представление графов
- •Нахождение кратчайших путей между парами вершин
4. 5. Когда рекурсию использовать не нужно
Рекурсивные алгоритмы особенно подходят для задач, где обрабатываемые данные определяются в терминах рекурсии. Однако это не означает, что такое рекурсивное определение данных гарантирует бесспорность употребления для решения задачи рекурсивного алгоритма. Фактически объяснение концепций рекурсивных алгоритмов на неподходящих для этого примерах и вызвало широко распространенное предубеждение против использования рекурсий в программировании; их даже сделали синонимом неэффективности.
Программы, в которых следует избегать алгоритмической рекурсии, можно охарактеризовать некоторой схемой, отражающей их строение (специфично, что тут есть единственное обращение к Р в конце или начале всей конструкции):
Р≡ IF В THEN (S; Р), 3.6
Р ≡ (S; IF В THEN Р). 3.7
Такие схемы естественны в ситуациях, где вычисляемые значения определяются с помощью простых рекуррентных отношений.
Например: вычисления факториала
i =0,1,2,3,4,5,….,
fi=1,1,2,6,24,120,…. 3.8
Первое из чисел определяется явно fо = 1, а последующие определяются рекурсивным образом с помощью предшествующего числа:
fi+1= (i+1)* fi 3.9
Такое рекуррентное отношение предполагает рекурсивный алгоритм вычисления n-го факториального числа.
Если мы введем две переменные I и F, обозначающие i и fi; на i-м уровне рекурсии, то для перехода к следующему числу последовательности нужно проделать такие вычисления:
I := I+1; F: I*F 3.10
и, подставляя (3.10) вместо S в (3.6), получаем рекурсивную программу:
Р≡ IF I<n THEN I:= I+1; F: = I*F; P END; 3.11
В первую строчку (3.11) можно переписать так:
FUNCTION P;
BEGIN
IF I < n THEN BEGIN I := I+1; F := I*F; P END
END; {P}
Более часто употребляется и полностью эквивалентная запись, где вместо Р приведена так называемая процедура-функция, т. е. процедура, с которой связывается значение-результат и которую поэтому можно применять прямо как составляющую выражения.
В этом случае переменная F становится излишней, а роль I явно выполняет параметр процедуры:
FUNCTION F (I: INTEGER): INTEGER; BEGIN IF I > 0 THEN F := I*F (I-l)
ELSE F := 1
END; {F}
Теперь уже ясно, что в рекурсия крайне просто заменяется итерацией. Это проделано в такой программе:
I := 0; F :=1;
WHILE I < n DO BEGIN I := I+1; F := I*F END;
Программы, построенные по схемам (3.6) и (3.7), нужно переписывать, руководствуясь схемой:
Р≡ [х: =х0 WHILE В DO S]. (3.15)
Следовательно, следует избегать рекурсий там, где есть очевидное итерационное решение. Однако это не означает, что от рекурсий следует избавляться любой ценой.
Существует много хороших примеров применения рекурсии,
То, что существуют реализации рекурсивных процедур на фактически нерекурсивных машинах, доказывает, что для практических целей любую рекурсивную программу можно трансформировать в итеративную.
Это требует явной работы со стеком для рекурсий, причем эти действия часто настолько затуманивают суть программы, что ее бывает трудно понять.
Алгоритмы, рекурсивные по своей природе, а не итеративные, нужно формулировать как рекурсивные процедуры.