Добавил:
Rumpelstilzchen2018@yandex.ru Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

3-й семестр / Лекция 1 - Нелинейные структуры данных

.pdf
Скачиваний:
54
Добавлен:
25.12.2020
Размер:
1.05 Mб
Скачать

1 Нелинейные структуры данных

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

1)Оглавление в книге

1.Раздел 1.

1.1. Глава 1

1.1.1Название темы

1.1.2Название темы 1.2. Глава 2

1.2.3Название темы

1.2.4Название темы 2. Раздел 2 2.3. Глава 1

2.3.5Название темы

2.3.6Название темы 2.4. Глава 2

2.4.7Название темы

2.4.8Название темы

2)Организационная диаграмма, представляющая структуру административного звена организации Ректор вуза

Проректор по учебной работе Декан факультета №1 Декан факультета №2

Проректор по научной работе Нач. отдела НИР Зав. аспирантурой

Проректор по хозяйственной части Главный инженер Комендант

3)Организационная диаграмма выполнения строительных работ при строительстве здания

Подводка водоснабжения

Сантехнические работы

Начало работ

Строительные работы

Закладка

Подвод коллектора

фундамента

 

Кровельные работы

4)Карта автомобильных дорог, карта авиационных перевозок, карта метро (например, Московского).

5)Файловая структура компьютера (дерево папок).

Во всех этих структурах данных между элементами существуют сложные отношения: иерархические или сетевые.

К нелинейным структурам данных относятся: 1.Дерево 2. Граф

3.Лес.

Для представления таких структур данных в программе можно использовать:

стандартные типы данных

линейные динамические списки

пользовательские типы данных, отражающие в памяти отношения между элементами структуру на основе указателей.

1.1Иерархические структуры данных (деревья)

Виерархической структуре данных, элементы подчинены отношению: у

каждого потомка есть только один предок.

Терминология деревьев

 

А

0 уровень (корень)

 

C

1 уровень

В

D

 

2 уровень

E

G

F

3 уровень

I

J

Рис.1. Дерево – иерархическая структура данных

На рисунке 1 представлена иерархическая структура данных В виде кружков представлены элементы, линии, их соединяющие, указывают связь узлов.

Данная модель представляет иерархические отношения между узлами. Узел А – корневой узел (предок или отец), он находится на нулевом

уровне, не имеет предков.

Узлы В, С, D – потомки (сыновья) узла А, находятся на уровне 1. Узел В является предком или отцом узлов Е и G.

Определение 1:

Дерево - это совокупность узлов, один из которых корень, и отношений, образующих иерархическую структуру.

Дерево может быть:

Пустым

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

может быть связано с несколькими узлами – корнями деревьев

(поддеревьев данного дерева). Определение 2:

n – ароное дерево

Пусть T1 ,T2 ,...,Tk - деревья с корнями n1, n2, n3 ….nк. Тогда можно

построить новое дерево Т, корнем которого будет узел n, а n1, n2, n3 ….nк - его поддеревьями.

Т

 

n

0 уровень (корень)

n1

n2

n3

 

1 уровень

 

nk

 

 

 

 

Т1

Т2

Т3

Тк

 

Рис. 2. Дерево с к поддеревьями Из опр. 1 видно, что структура определена с помощью рекурсии, поэтому

можно ввести следующее определение дерева с базовым типом T .

Дерево типа Т это:

1.

Пустая структура или

2.

Состоит из 1-го узла n типа T или

3.

Состоит из узла, с которым связано конечное число древовидных

 

структур с корнями (n1,n2,…nk) базового типа T , называемых

 

поддеревьями .

Основные понятия:

1.В деревьях действует отношение: у каждого потомка только один предок.

2.Каждый узел – это корень своего дерева или поддерево родителя.

3.Узел, который не имеет предков, называют корневым узлом.

4.Высота дерева –кол-во ребер между корнем и максимально удаленным узлом или максимальный уровень.

Высота дерева, представленного на рис.1. равна 3.

5.Лист дерева – узел, который не имеет потомков.

Листья дерева на рис.1.:E, I, J, F, D.

6. Степень узла – число непосредственных потомков.

Степень узла A на рис.1 равна 3, а степень узла G равна 0, степнь узла C – 1

7.Степень дерева - максимальная степень его узлов. Дерево на рис.1 имеет степень 3.

8.Путь в дереве – последовательность узлов от корня к указанному узлу.

Пример. Путь к узлу J в дереве на рис.1: A B F J.

8. Длина пути в дереве до узла – кол-во ребер от корня до узла или номер уровня, на котором находится узел. Длина пути до узла J в дереве рис.1 равна 3.

9.Длина пути в дереве равна сумме длин всех его ребер. Для рассматриваемого дерева длина пути равна 8.

10.Упорядоченные и неупорядоченные деревья

Дерево считается упорядоченным, если существует порядок перечисления узлов. Порядок узлов определяется обычно так: сыновья упорядочены слева направо: «левый» сын и его «правые» братья.

Так для дерева А рис.1.узел В – это левый сын, С и D его правые братья, но все они сыновья А.

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

На рисунке 3 представлены два разных упорядоченных дерева, так как их сыновья перечислены по разному.

Рис. 3. Разные упорядоченные деревья

11.Помеченные деревья - узлы, которых имеют метки – имена или номера.

12.Сбалансированное дерево– дерево, высота поддеревьев которого отличается не более чем на единицу.

Виды деревьев.

1.Сильно ветвящиеся деревья (степень дерева >2).

2.Двоичное (бинарное) дерево (степень дерева <=2)..

3.Двоичное сбалансированное дерево.

4.Двоичное дерево поиска.

5.Двоичное сбалансированное дерево поиска (AVL – дерево).

2 Реализация деревьев

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

2.1 На массиве родителей.

Массив содержит такое количество элементов, сколько узлов в дереве. Индексами массива являются метки узлов дерева. Элементы массива содержат индексы (метки) родителей соответствующих узлов. Данные узла можно хранить в элементе массива или отдельном массиве.

Рассмотрим дерево, узлы которого имеют числовые метки.

5

 

 

7

 

 

 

6

 

 

 

8

 

 

 

 

 

 

 

 

 

 

4

 

9

 

 

10

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Массив родителей этого дерева:

 

 

 

1

2

3

4

5

6

7

8

9

10

Метки узлов

-1

-1

-1

7

0

5

5

5

7

7

Ссылки на родителей (их метки)

Как найти корень? Сыновей?

Способы программной реализации массива родителей.

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

const Maxlen=100;

typedef unsigned int[MaxLen] Tree; //реализация отношений typedef TDataNode[MaxLen] infoNodeTree;

Tree TreeParents; //дерево – представленное массивом родителей nfoNodeTree InfoTree;

Способ 2. Определение всех параметров дерева в одной структуре.

Struct Tree{

 

unsigned int Tree [MaxLen];

//массив родителей

TDataNode infoNodeTree[MaxLen];//массив значений

n:byte;

//количество узлов

};

T:Ttree;

Примеры использования рассмотренных представлений

Пример 1. Поиск левого сына узла

Задачи поиска сыновей узла: левого сына и правого брата для данной реализации не выполнима, если не ввести нумерацию сыновей последовательно слева направо, например, так, как в примерах

A)

1

 

 

2

 

 

3

 

 

 

 

5

 

6

7

4

 

 

 

 

 

 

 

 

 

5

B)

 

1

5

7

 

 

 

12

13

14

 

C)

5

 

 

 

6

7

 

8

 

 

 

 

 

 

 

9

10

11

 

 

 

 

 

 

 

 

 

Рис.4. Деревья с узлами, пронумерованными в порядке возрастания

1

2

3

4

5

6

7

0

1

1

1

2

2

2

Для поиска левого сына узла 2 в дереве А) рисунка 4, при использовании массива родителей, достаточно найти первый элемент массива со значением равным 2.

//левый сын это первый узел со значением i

//предусловие: i < T.n

//постусловие: возвращает номер элемента массива

//T.TreeParents значением которого является i

//или -1 если такого значения нет в массиве int leftSon(Ttree T;int i) //первый узел со значением i

int j=1;

while (j<=T.n && T.TreeParents[j]!=i) {

j++;

if (j<=T.n) return j;

}

return -1;

}

Пример 2. Поиск правого брата заданного узла.

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

//Поиск родителя узла node int Parent(Tree Tt, int i){

return T.TreeParents[i];

}

//Поиск правого брата

int rightBrather(Tree T, int i){ int j,p;

p=Parent(T,i); //Метка родителя узла node

//Поиск правого брата с узла следующего за исходным if (T[i+1]==p) return (i+1);

else return -1;;

}

2.2 Список сыновей.

Представление дерева основано на линейном списке.

Пусть требуется представить в памяти дерево (рис.5) на основе списка сыновей.

 

 

 

1

 

2

 

 

3

 

 

 

 

 

4

 

5

 

 

 

 

9

10

 

 

 

6

7

 

8

 

Рис.5. Представление n-арного дерева

На рис. 6. изображена структура, где массив head – массив родителей, который содержит ссылки на списки сыновей. Индексы массива head – это

метки узлов. Первый узел списка – это левый сын. Если узел не имеет потомков, то в массиве head ссылка равна nil.

 

 

 

Ссылка

 

 

 

 

head

 

на

 

 

 

 

 

правого

 

 

 

 

Метка узла

Данные

 

 

 

 

брата

 

 

 

 

 

 

 

 

 

1

2

100

3

200

 

 

 

2

 

3

 

 

 

2

4

400

5

500

 

 

3

9

900

10

1000

 

 

4

nil

 

 

 

 

 

5

6

600

7

700

8

800

6nil

7nil

8

nil

 

9

nil

10

nil

Рис. 6. Реализация дерева с использованием связанных списков

Реализация данной структуры приведена в нижеследующем примере. В нем рассматривается один из алгоритмов создания дерева, вставки в него новых узлов – сыновей других узлов. Для поиска сыновей в дереве предусмотрено упорядочение сыновей слева направо по номеру метки, поэтому списки сыновей следует создавать упорядоченными по меткам.

Пример 4. Реализация дерева на списках сыновей.

Модуль содержит операции по созданию дерева и поиску в дереве левых сыновей заданных узлов и правых братьев. Процедура Obxod выводит дерево в виде: родитель и его сыновья.

struct Tnode{ Tinfo info; Tnode *next;

};

struct Tree{

Tnode *L[MaxLen]; int n;

};

Tree T;

2.3Представление дерева через список левых сыновей и правых братьев.

3.1.Реализация на курсоре Курсором называют структуру данных, построенную на массиве,

содержащем индексы (ссылки) на другие элементы этого массива или другого. На рисунке 7 представлено дерево, реализованное на двух массивах: первый массив содержит метки левых сыновей узлов (родителей), второй массив содержит ссылки на правых братьев узлов. Стрелками показана последовательность поиска всех сыновей узла 1. Так же можно найти сыновей других узлов. Дерево данной реализации можно определить так:

Выполните реализацию всех операций примера 4 для этого представления дерева .

1

 

 

2

 

 

 

7

 

 

8

 

 

 

 

 

 

 

 

 

 

5

 

 

 

9

 

 

 

 

 

 

 

 

 

 

 

 

 

6

3

 

 

4

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2

5

0

0

6

0

0

0

0

Список родителей с указателем на

левых сыновей

 

 

 

 

 

 

 

 

 

1

2

3

4

5

6

7

8

9

 

0

7

4

0

9

3

8

0

0

Список левых сыновей с указателями

на правых братьев

 

 

 

 

 

 

 

 

 

1

2

3

4

5

6

7

8

9

 

Рис. 7. Дерево, реализованное на списке левых сыновей и правых братьев

3.2. Реализация дерева на таблице «левых» сыновей и «правых» братьев

Дерево, узлы в котором

Индексы

индекс

метка

индекс

помечены буквами

элементов

левых

 

правых

 

таблицы

сыновей

 

братьев

 

1

0

D

0

 

2

 

 

 

 

3

 

 

 

 

4

0

B

10

 

5

 

 

 

 

6

 

 

 

 

7

 

 

 

 

8