Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка3.2.doc
Скачиваний:
37
Добавлен:
19.08.2019
Размер:
3.14 Mб
Скачать

-103-

Лабораторная работа № 1 структура данных дерево

Цель работы: изучить структуру данных дерево, разработать класс TTree для работы с ней и получить практический навык его использования.

Теоретические сведения

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

Дерево (Tree) – это структура данных, представленная в виде нелинейного списка и предназначенная для хранения информации в иерархическом виде.

Структура дерева состоит из множества узлов (Nodes), один их которых является начальным – корень дерева (Root). Узлы соединяются между собой ветвями или ребрами (Edges). Каждый узел может иметь несколько наследников (Children). Если узел имеет хотя бы одного наследника, то его называют родителем (Parent). Узел, не имеющий детей, называется листом (Leaf).

Рис. 1. Структура дерева общего вида

В отличие от других нелинейных структур данных, каждый узел дерева может иметь только одного родителя и множество наследников. Сыновья узла и сыновья их сыновей называются потомками (Descendants), а родители и прародители – предками (Ancestors). Если узел не является корнем дерева, то он и всего его потомки образуют собственное поддерево (SubTree), а сам он выступает в качестве его корня.

Путь от корня до узла дает такую характеристику как уровень (Level). Уровень корня принят за ноль. Каждый сын корня является узлом 1-го уровня, следующее поколение – 2-го уровня и т.д.

Максимальный уровень, определяющий самый длинный путь от корня дерева до любого его узла, называется глубиной дерева (Depth).

Дерево, каждый узел которого имеет не более одного наследника, называется вырожденным, а не более двух – бинарным (рис. 2).

Рис. 2. Структура вырожденного и бинарного деревьев

а) вырожденное дерево; б) бинарное дерево

Вырожденные деревья становятся эквивалентом связанного списка и имеют самую маленькую плотность – отношение числа узлов к глубине дерева.

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

  1. Прямое (Direct Scan). Проход дерева осуществляется в порядке ‘NodeChildren’ (NC).

  2. Обратное (Revers Scan). Проход дерева осуществляется в порядке ‘ChildrenNode' (CN).

  3. Поперечное (Level Scan). Проход дерева осуществляется по уровням, начиная с корня.

  4. Симметричное. Проход дерева осуществляется в порядке ‘LeftChildNodeRightChild’ (CN). Полностью может быть реализовано только для бинарных деревьев.

Например, для дерева, представленного на рис. 2, результат прохождения будет следующим:

A B D C E // прямой проход

D B E C A // обратный проход

A B C D E // поперечный проход

D B A C E // симметричный проход

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

Алгоритм прямого прохода реализуется следующим образом:

Шаг 1. Выполняют действия с данными узла, передаваемого в списке параметров.

Шаг 2. Если узел не является листом, то для всех его детей рекурсивно выполняется первый шаг.

Алгоритм обратного прохождения реализуется также, если поменять первый и второй шаг местами:

Шаг 1. Если узел не является листом, то для всех его детей рекурсивно повторяется первый шаг.

Шаг 2. Выполняют действия с данными узла, передаваемого в списке параметров.

Алгоритм симметричного прохождения реализуется следующим образом:

Шаг 1. Если узел имеет левого сына, то повторяется первый шаг для его левого сына.

Шаг 2. Если узел имеет правого сына, то повторяется первый шаг для его правого сына.

Шаг 3. Выполняют действия с данными самого узла, передаваемого в списке параметров.

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

Для построения дерева необходимо использовать такую структуру данных как узел. Она может быть реализована в виде пользовательского класса TTreeNode, содержащего все необходимые данные об узле и методы работы с ним.

ADT – формат класса TTreeNode

ADT TTreeNode

Поля

Указатель на родительский узел (FParent): Тип узла

Данные узла (FData): Заданный тип

Уровень узла (FLevel): Целый тип

Список дочерних узлов (Items): Динамический массив узлов vector

Счетчик узлов (FCount): Целый тип

Методы

Конструктор

Вход: Родительский узел и данных нового узла

Предусловие: Нет

Начальные значения: Нет

Процесс: Инициализация полей объекта

Добавление дочернего узла (AddChild)

Вход: Данные дочернего узла

Предусловие: Нет

Процесс: Создание нового узла и добавление его в конец списка узлов

Постусловие: Новый элемент добавлен в конец списка и счетчик узлов увеличен на единицу.

Выход: Указатель на созданный узел

Вставка дочернего узла в указанную позицию (InsetChild)

Вход: Родительский узел, порядковый номер в списке родителя и данные нового узла.

Предусловие: Порядковый номер узла меньше количества узлов и не меньше нуля.

Процесс: Создание нового узла и добавление его в указанную позицию списка дочерних узлов.

Постусловие: Новый элемент добавлен в указанную позицию списка, и счетчик узлов увеличен на единицу.

Выход: Указатель на созданный узел

Удаление дочернего узла (DeleteChild)

Вход: Индекс узла в списке родителя

Предусловие: Порядковый номер узла меньше количества узлов и не меньше нуля.

Процесс: Удаление узла из списка родителя и упорядочивание в нем оставшихся элементов.

Постусловие: Счетчик узлов и длина дочернего списка уменьшены на единицу.

Выход: Нет

Деструктор (Destroy)

Вход: Нет

Предусловие: Нет

Процесс: Удаление из памяти всех дочерних узлов из списка.

Конец ADT TTreeNode