|
|
| Новости |
ДВОИЧНЫЕ ДЕРЕВЬЯ В этом разделе рассматривается четвертая структура данных,
которая называется двоичным деревом. Имеется много типов деревь-
ев. Однако, двоичные деревья занимают особое положение. Если та-
кие деревья упорядочить, то операции поиска, вставки и удаления
будут выполняться очень быстро. Каждый элемент двоичного дерева
имеет информационные поля, связь с левым элементом и связь с пра-
вым элементом. На рис.14 показано небольшое дерево.
При описании деревьев используется специальная терминология.
Первый элемент дерева называется его корнем. Каждый элемент назы-
вают вершиной /или листом/ дерева, а часть дерева носит название
поддерева. Вершина, которая не имеет поддеревьев, называется тер-
минальной вершиной. Высота дерева равна числу уровней вершин в
дереве. В дальнейшем при рассмотрении деревьев можно считать, что
в памяти они располагаются так же, как на бумаге. Однако следует
помнить, что деревья представляют собой лишь способ представления
данных в памяти, а память в действительности имеет линейную фор-
му.
Root Node 1
+-------+
¦2 info ¦
+-------¦
¦ ¦ ¦
3 +-------+ 4
Left Subtree Righl Subtree
+-------+ +-------+
¦ 2 info¦ ¦2 info ¦
+-------¦ +-------¦
¦ ¦ ¦ 5¦nil¦ ¦
+-------+ +-------+
+-------+ +-------+ +-------+
¦2 info ¦ ¦2 info ¦ ¦2 info ¦
+-------¦ +-------¦ +-------¦
5¦nil¦nil¦5 5¦nil¦nil¦5 5¦nil¦nil¦5
+-------+ +-------+ +-------+
6
Terminal Nodes
Рис.14. Пример двоичного дерева:
1 - корневая вершина; 2 - информационные поля; 3 - левое
поддерево; 5 - указатель связи с нулевым значением; 6 - терми-
нальные вершины.
Двоичное дерево представляет собой особую форму связанного
списка. Доступ к элементам, их вставка и удаление могут выпол-
няться в любом порядке. Кроме того, операция поиска не носит раз-
рушительный характер. Хотя деревья легко представляются образно,
для программирования они представляют достаточно непростую зада-
чу. Поэтому они стали рассматриваться лишь в этом разделе.
Большинство функций над деревьями носят рекурсивный харак-
тер, поскольку дерево само по себе является рекурсивной структу-
рой данных. /Т.е. каждое поддерево само является деревом/. Поэто-
му представленные в этом разделе программы являются, как правило,
рекурсивными. Имеются нерекурсивные версии этих функций, однако
разобраться в них значительно труднее.
Упорядоченность дерева зависит от порядка доступа к дереву.
Процесс доступа к каждой вершине дерева называется обходом дере-
ва.
Имеется три способа обхода дерева: во внутреннем порядке, в
прямом порядке и в обратном порядке. При прохождении дерева во
внутреннем порядке сначала посещается левое поддерево, затем ко-
рень и затем посещается правое дерево. При прохождении дерева в
прямом порядке сначала посещается корень, затем левое поддерево и
затем правое поддерево. При прохождении дерева в обратном порядке
сначала посещается левое поддерево, затем правое поддерево и за-
тем корень.
Порядок прохождения ds, выбранного в качестве примера дерева
будет следующим:
- при прохождении во внутреннем порядке: a b c d e f g;
- при прохождении в прямом порядке: d b a c f e g;
- при прохождении в обратном порядке: a c b e g f d.
Хотя дерево не обязательно должно быть упорядочено, в боль-
шинстве случаев оно должно быть таким. Упорядоченность дерева за-
висит от того, как вы будете проходить дерево. В приводимых ниже
примерах используется внутренний порядок прохода по дереву. В от-
сортированном двоичном дереве левое поддерево содержит вершины,
которые меньше или равны корню, а вершины правого поддерева боль-
ше или равны корню. Ниже приводится функция, которая выполняет
построение отсортированного двоичного дерева:
type
TreePointer = ^tree;
tree = record
data: char;
left: TreePointer;
right:TreePointer;
end;
{ добавить элемент в двоичное дерево }
function Stree(root,r:TreePointer;data:char);TreePointer;
begin
if r=nil then
begin
new(r); { получить новую вершину }
r^.left:=nil;
r^right:=nil;
r^.data:=data;
if data
|
|
(с)Все права защищеныПо всем интересующим вопросампрошу писать на электронный адрес
|