VB, MS Access, VC++, Delphi, Builder C++ принципы(технология), алгоритмы программирования
| Категория реферата: Рефераты по информатике, программированию
| Теги реферата: презентация дипломной работы, отчет по производственной практике
| Добавил(а) на сайт: Памфил.
Предыдущая страница реферата | 32 33 34 35 36 37 38 39 40 41 42 | Следующая страница реферата
Полные деревья
Полное дерево (complete tree) содержит максимально возможное число узлов на
каждом уровне, кроме нижнего. Все узлы на нижнем уровне сдвигаются влево.
Например, каждый уровень троичного дерева содержит в точности три дочерних
узла, за исключением листьев, и возможно, одного узла на один уровень выше
листьев. На рис. 6.9 показаны полные двоичное и троичное деревья.
Полные деревья обладают рядом важных свойств. Во-первых, это кратчайшие
деревья, которые могут содержать заданное число узлов. Например, двоичное
дерево на рис. 6.9 — одно из самых коротких двоичных деревьев с шестью
узлами. Существуют другие двоичные деревья с шестью узлами, но ни одно из
них не имеет высоту меньше 3.
Во-вторых, если полное дерево порядка D состоит из N узлов, оно будет иметь
высоту порядка O(logD(N)) и O(N) листьев. Эти факты имеют большое значение, поскольку многие алгоритмы обходят деревья сверху вниз или в
противоположном направлении. Время выполнения алгоритма, выполняющего одно
из этих действий, будет порядка O(N).
Чрезвычайно полезное свойство полных деревьев заключается в том, что они
могут быть очень компактно записаны в массивах. Если пронумеровать узлы в
«естественном» порядке, сверху вниз и слева направо, то можно поместить
элементы дерева в массив в этом порядке. На рис. 6.10 показано, как можно
записать полное дерево в массиве.
Корень дерева находится в нулевой позиции. Дочерние узлы узла I находятся
на позициях 2 * I + 1 и 2 * I + 2. Например, на рис. 6.10, потомки узла в
позиции 1 (узла B), находятся в позициях 3 и 4 (узлы D и E).
Легко обобщить это представление на полные деревья более высокого порядка
D. Корень дерева также будет находиться в позиции 0. Потомки узла I
занимают позиции от D * I + 1 до D * I +(I - 1). Например, в троичном
дереве, потомки узла в позиции 2, будут занимать позиции 7, 8 и 9. На рис.
6.11 показано полное троичное дерево и его представление в виде массива.
@Рис. 6.9. Полные деревья
=========127
@Рис. 6.10. Запись полного двоичного дерева в массиве
При использовании этого метода записи дерева в массиве легко и просто получить доступ к потомкам узла. При этом не требуется дополнительной памяти для коллекций дочерних узлов или меток в случае представления нумерацией связей. Чтение и запись дерева в файл сводится просто к сохранению или чтению массива. Поэтому это несомненно лучшее представление дерева для программ, которые сохраняют данные в полных деревьях.
Обход дерева
Последовательное обращение ко всем узлам называется обходом (traversing)
дерева. Существует несколько последовательностей обхода узлов двоичного
дерева. Три простейших из них — прямой (preorder), симметричный (inorder), и обратный (postorder)обход, описываются простыми рекурсивными алгоритмами.
Для каждого заданного узла алгоритмы выполняют следующие действия:
Прямой обход:
1. Обращение к узлу.
2. Рекурсивный прямой обход левого поддерева.
3. Рекурсивный прямой обход правого поддерева.
Симметричный обход:
1. Рекурсивный симметричный обход левого поддерева.
2. Обращение к узлу.
3. Рекурсивный симметричный обход левого поддерева.
Обратный обход:
1. Рекурсивный обратный обход левого поддерева.
2. Рекурсивный обратный обход правого поддерева.
3. Обращение к узлу.
@Рис. 6.11. Запись полного троичного дерева в массиве
=======128
Все три порядка обхода являются примерами обхода в глубину (depth-first
traversal). Обход начинается с прохода вглубь дерева до тех пор, пока
алгоритм не достигнет листьев. При возврате из рекурсивного вызова
подпрограммы, алгоритм перемещается по дереву в обратном направлении, просматривая пути, которые он пропустил при движении вниз.
Обход в глубину удобно использовать в алгоритмах, которые должны вначале
обойти листья. Например, метод ветвей и границ, описанный в 8 главе, как
можно быстрее пытается достичь листьев. Он использует результаты, полученные на уровне листьев для уменьшения времени поиска в оставшейся
части дерева.
Четвертый метод перебора узлов дерева — это обход в ширину (breadth-first
traversal). Этот метод обращается ко всем узлам на заданном уровне дерева, перед тем, как перейти к более глубоким уровням. Алгоритмы, которые
проводят полный поиск по дереву, часто используют обход в ширину. Алгоритм
поиска кратчайшего маршрута с установкой меток, описанный в 12 главе, представляет собой обход в ширину, дерева кратчайшего пути в сети.
На рис. 6.12 показано небольшое дерево и порядок, в котором перебираются
узлы во время прямого, симметричного и обратного обхода, а также обхода в
ширину.
@Рис. 6.12. Обходы дерева
======129
Для деревьев больше, чем 2 порядка, все еще имеет смысл определять прямой, обратный обход, и обход в ширину. Симметричный обход определяется
неоднозначно, так как обращение к каждому узлу может происходить после
обращения к одному, двум, или трем его потомкам. Например, в троичном
дереве, обращение к узлу может происходить после обращения к его первому
потомку или после обращения ко второму потомку.
Детали реализации обхода зависят от того, как записано дерево. Для обхода
дерева на основе коллекций дочерних узлов, программа должна использовать
несколько другой алгоритм, чем для обхода дерева, записанного при помощи
нумерации связей.
Особенно просто обходить полные деревья, записанные в массиве. Алгоритм
обхода в ширину, который требует дополнительных усилий в других
представлениях деревьев, для представлений на основе массива тривиален, так
как узлы записаны в таком же порядке.
Следующий код демонстрирует алгоритмы обхода полного двоичного дерева:
Dim NodeLabel() As String ' Запись меток узлов.
Dim NumNodes As Integer
' Инициализация дерева.
:
Private Sub Preorder(node As Integer)
Print NodeLabel (node) ' Узел.
' Первый потомок.
If node * 2 + 1 FOX.
Таким же образом можно закодировать строки из 6 заглавных букв в виде числа
в формате long и строки из 10 букв — как число в формате double. Две
следующие процедуры конвертируют строки в числа в формате double и обратно:
Const STRING_BASE = 27
Const ASC_A = 65 ‘ ASCII код для символа "A".
‘ Преобразование строки с число в формате double.
‘
‘ full_len — полная длина, которую должна иметь строка.
‘ Нужна, если строка слишком короткая (например "AX" —
‘ это строка из трех символов).
Function StringToDbl (txt As String, full_len As Integer) As Double
Dim strlen As Integer
Dim i As Integer
Dim value As Double
Dim ch As String * 1
strlen = Len(txt)
If strlen > full_len Then strlen = full_len
value = 0#
For i = 1 To strlen ch = Mid$(txt, i, 1) value = value * STRING_BASE + Asc(ch) - ASC_A + 1
Next i
For i = strlen + 1 To full_len value = value * STRING_BASE
Next i
End Function
‘ Обратное декодирование строки из формата double.
Function DblToString (ByVal value As Double) As String
Dim strlen As Integer
Dim i As Integer
Dim txt As String
Dim Power As Integer
Dim ch As Integer
Dim new_value As Double
txt = ""
Do While value > 0 new_value = Int(value / STRING_BASE) ch = value - new_value * STRING_BASE
If ch 0 Then txt = Chr$(ch + ASC_A - 1) + txt value = new_value
Loop
DblToString = txt
End Function
===========228
В табл. 9.1 приведено время выполнения программой Encode сортировки 2000 строк различной длины на компьютере с процессором Pentium и тактовой частотой 90 МГц. Заметим, что результаты похожи для каждого типа кодирования. Сортировка 2000 чисел в формате double занимает примерно одинаковое время независимо от того, представляют ли они строки из 3 или 10 символов.
========229
@Таблица 9.1. Время сортировки 2000 строк с использованием различных кодировок в секундах
Можно также кодировать строки, состоящие не только из заглавных букв.
Строку из заглавных букв и цифр можно закодировать по основанию 37 вместо
27. Код буквы A будет равен 1, B — 2, … , Z — 26, код 0 будет 27, … , и 9 —
36. Строка AH7 будет кодироваться как 372 * 1 + 37 * 8 + 35 = 1700.
Конечно, при использовании большего основания, длина строки, которую можно
закодировать числом типа integer, long или double будет соответственно
короче. При основании равном 37, можно закодировать строку из 2 символов в
числе формата integer, из 5 символов в числе формата long, и 10 символов в
числе формата double.
Примеры программ
Чтобы облегчить сравнение различных алгоритмов сортировки, программа Sort
демонстрирует большинство алгоритмов, описанных в этой главе. Сортировка
позволяет задать число сортируемых элементов, их максимальное значение, и
порядок расположения элементов - прямой, обратный или расположение в
случайном порядке. Программа создает список случайно расположенных чисел в
формате long и сортирует его, используя выбранный алгоритм. Вначале
сортируйте короткие списки, пока не определите, насколько быстро ваш
компьютер может выполнять операции сортировки. Это особенно важно для
медленных алгоритмов сортировки вставкой, сортировки вставкой с
использованием связного списка, сортировки выбором, и пузырьковой
сортировки.
Некоторые алгоритмы перемещают большие блоки памяти. Например, алгоритм
сортировки вставкой перемещает элементы списка для того, чтобы можно было
вставить новый элемент в середину списка. Для перемещения элементов
программе, написанной на Visual Basic, приходится использовать цикл For.
Следующий код показывает, как сортировка вставкой перемещает элементы с
List(j) до List(max_sorted) для того, чтобы освободить место под новый
элемент в позиции List(j):
For k = max_sorted To j Step -1
List(k + 1) = List(k)
Next k
List(j) = next_num
==========230
Интерфейс прикладного программирования системы Windows включает две
функции, которые позволяют намного быстрее выполнять перемещение блоков
памяти. Программы, скомпилированные 16-битной версией компилятора Visual
Basic 4, могут использовать функцию hmemcopy. Программы, скомпилированные
32-битными компиляторами Visual Basic 4 и 5, могут использовать функцию
RtlMoveMemory. Обе функции принимают в качестве параметров конечный и
исходный адреса и число байт, которое должно быть скопировано. Следующий
код показывает, как объявлять эти функции в модуле .BAS:
#if Win16 Then
Declare Sub MemCopy Lib "Kernel" Alias _
"hmemcpy" (dest As Any, src As Any, _
ByVal numbytes As Long)
#Else
Declare Sub MemCopy Lib "Kernel32" Alias _
Рекомендуем скачать другие рефераты по теме: доклад по химии, конспект зима.
Категории:
Предыдущая страница реферата | 32 33 34 35 36 37 38 39 40 41 42 | Следующая страница реферата