Студопедия
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Никифорак М.В. Удаление узла производится только тогда, когда узел не пустой и его левый и правый сыновья уже удалены.

Читайте также:
  1. Никифорак М.В.
  2. Никифорак М.В.
  3. Никифорак М.В.
  4. Никифорак М.В.
  5. Никифорак М.В.

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

Команда root=NULL имеет смысл только когда удаляется корень дерева.

3.4. Операции с идеально сбалансированными деревьями

Построение дерева

Рассмотрим подпрограмму create (int number, tree *&root), которая используется для формирования идеально сбалансированного дерева. Она имеет два формальных параметра: number – количество узлов в формируемом дереве; root – указатель на корень дерева. Первый узел полагается корнем формируемого дерева, после чего определяется количество узлов в левом поддереве numberLeft = number/2, количество узлов в правом поддереве numberRight = number- numberLeft -1. Далее numberLeft узлов рекурсивно заносится в левое поддерево текущего узла, оставшиеся numberRight узлов рекурсивно заносятся в правое поддерево текущего узла. Таким образом, для каждого узла количество узлов в левом поддереве отличается от количества узлов в правом поддереве не больше чем на единицу.

 

void create (int number, tree *&root)

{int a;

if (number>0)

{

root=new tree;

cin>>a;

root->inf=a;

root->left=root->right=NULL;

int numberLeft=number/2, numberRight=number-numberLeft-1;

create(numberLeft, root->left);

create(numberRight, root->right); }

}

 

Пример 7. Если во входном файле указать количество узлов 10, а затем перечислить те же самые узлы, что и в примере 3 (10, 7, 25, 31, 18, 6, 3, 12, 22, 8), то получим дерево, представленное на рис. 3.6.

 

 

 

Рис. 3.6. Идеально сбалансированное дерево

 

Поиск по дереву

Для реализации поиска элемента в идеально сбалансированном дереве можно использовать модификацию любого вида обхода дерева. В следующем листинге будет приведена модификация прямого обхода:

 

void search (int x, tree *root)

{if (root) // если дерево не пустое

 

if (x==root->inf) /* и значение узла равно x, то выводим сообщение об успешности поиска и выходим из подпрограммы */

{ cout<<"search is successful";return; }

 

else {search(x, root->left); // иначе обходим левое и правое поддеревья

search(x, root->right);

}

}

Удаление дерева

Операция удаления идеально сбалансированного дерева ничем не отличается от удаления дерева двоичного поиска (см. 3.2. Операции с деревьями двоичного поиска).

 

3.3. Решение практических задач с использованием деревьев

1. В файле input.txt хранится последовательность целых чисел. Построить по этой последовательности дерево двоичного поиска и вывести в файл output.txt листья этого дерева.

 

_____________________________prim1.cpp_______________________________

 

#include <fstream>

using namespace std;

ifstream in("input.txt");

ofstream out("output.txt");

struct tree

{

int inf;

tree *left, *right;

};

tree *root;

 

void add (int x, tree *&root)

{if (!root)

{

root=new tree;

root->inf=x;

root->left=root->right=NULL;

}

else if (x<root->inf)

add(x,root->left);

else

if (x>root->inf)

add(x,root->right);

}

void deleteTree(tree *&root)

{ if (root)

{deleteTree(root->left);

deleteTree(root->right);

delete root;

root=NULL;}

}

 

void printList(tree *root)

{if (root) //если узел не пустой

 

{ /* и если у узла отсутствуют левое и правое поддеревья, то узел является листом и мы его распечатываем*/

if (root->left==NULL && root->right==NULL) out<<root->inf<<"\t";

 

else {printList(root->left); printList(root->right);} //иначе выполняем обход узла

}

}

 

 

int main()

{

int x;

while (!in.eof())

{

in>>x;

add(x,root);

}

 

printList(root);

deleteTree(root);

in.close();

}

 

 

_____________________________input.txt_________________________________

 

10 7 25 31 18 6 3 12 22 8

 

_____________________________output.txt________________________________

 

3 8 12 22 31

 

Замечание. Во входном файле были приведены данные, соответствующие примеру 3.

 

2. В файле input.txt в первой строке записано N, во второй строке – последовательность из N целых чисел. Построить по этой последовательности идеально сбалансированное дерево и вывести в файл output.txt высоту этого дерева.

 

_____________________________prim2.cpp_______________________________

 

#include <fstream>

using namespace std;

ifstream in("input.txt");

ofstream out("output.txt");

struct tree

{

int inf;

tree *left, *right;

};

tree *root;

 

void deleteTree(tree *&root)

{ if (root) // если узел дерева не пуст, то

{deleteTree(root->left); // обходим левое и

deleteTree(root->right); // правое поддеревья этого узла

delete root; // после чего удаляем сам узел

root=NULL;}

}

 

void create (int number, tree *&root)

{int a;

if (number>0)

{

root=new tree;

in>>a;

root->inf=a;

root->left=root->right=NULL;

int numberLeft=number/2, numberRight=number-numberLeft-1;

create(numberLeft, root->left);

create(numberRight, root->right); }

}

 

void heightTree(tree *root, int &heightNode, int &height)

{if (root) // если текущий узел не пустой

{if (heightNode>height) // и высота текущего узла больше высоты дерева, то

height=heightNode; // полагаем в качестве высоты дерева высоту текущего узла

heightNode++; // в любом случае увеличиваем высоту текущего узла на 1 и

heightTree(root->left, heightNode, height); // обходим левое и правое его поддеревья

heightTree(root->right, heightNode, height);

 

heightNode--; // после обхода узла высоту текущего узла уменьшаем на 1

}

/* если попали в пустой узел, то завершаем рекурсию и высоту узла уменьшаем на 1 */

else heightNode--;

}

 

 

void printList(tree *root)

{if (root) //если узел не пустой

 

{ /* и если у узла отсутствуют левое и правое поддеревья, то узел является листом и мы его распечатываем*/

if (root->left==NULL && root->right==NULL) out<<root->inf<<"\t";

 

else {printList(root->left); printList(root->right);} //иначе выполняем обход узла

}

}

 

 

int main()

{int n;

in>>n;

create(n,root);

 

 

int currentHeight=0,resultHeight=0; //инициализируем данные, необходимые для работы подпрограммы

heightTree(root,currentHeight,resultHeight); // вызываем функцию, подсчитывающую высоту дерева

out<<resultHeight<<endl; // выводим высоту дерева в выходной файл

deleteTree(root);

in.close();

}

 

 

_____________________________input.txt_________________________________

 

10 7 25 31 18 6 3 12 22 8

 

_____________________________output.txt________________________________

 

Замечание. Во входном файле были приведены данные, соответствующие примеру 7.

 

3. В файле input.txt хранится последовательность целых чисел. Построить по этой последовательности дерево двоичного поиска и вывести в файл output.txt путь из вершины a в вершину b этого дерева (если путь не существует, то вывести сообщение об этом).

 

_____________________________prim3.cpp_______________________________

 

#include <fstream>

#include <queue>

using namespace std;

ifstream in("input.txt");

ofstream out("output.txt");

struct tree

{

int inf;

tree *left, *right;

};

tree *root;

 

void add (int x, tree *&root)

{if (!root)

{

root=new tree;

root->inf=x;

root->left=root->right=NULL;

}

else if (x<root->inf)

add(x,root->left);

else

if (x>root->inf)

add(x,root->right);

}

void deleteTree(tree *&root)

{ if (root)

{deleteTree(root->left);

deleteTree(root->right);

delete root;

root=NULL;}

}

 

 

// Функция возвращает указатель на узел в дереве root, имеющий значение value

tree * searchNode (tree *root, int value)

{

if (!root) // если узел пустой, то узел со значением value в дереве не встречается

return NULL; // и мы возвращаем пустой указатель,

 

else

if (value<root->inf) // иначе если значение value меньше значения узла,

searchNode(root->left,value); // то спускаемся по левому поддереву,

 

else

if (value>root->inf) // иначе если значение value больше значения узла,

searchNode(root->right, value); // то спускаемся по правому поддереву,

 

// иначе заданный узел найден, и мы возвращаем указатель на него

else

return root;

}

 

/* Рекурсивная функция, определяющая путь от заданного узла до узла со значением value. Формальные параметры: currentNode – указатель на заданный узел дерева; value – значение узла, путь до которого нужно найти; q- очередь, в которую будет записываться путь. */

void way(tree *currentNode, int value, queue<int> &q)

{

if (!currentNode) // если узел пустой, то узел со значением value в дереве не встречается

 

while (!q.empty())

{

q.pop();

}

 

// и мы удаляем последовательность узлов пути из очереди,

 

else

{

q.push(currentNode->inf); // иначе помещаем текущий узел в очередь

 

if (value<currentNode->inf) // и если значение value меньше значения узла,

way(currentNode->left, value, q); // то спускаемся по левому поддереву,

else

if (value>currentNode->inf) // иначе если значение value больше значения узла,

way(currentNode->right, value, q); // то спускаемся по правому поддереву,

// иначе значение узла равно value и мы завершаем рекурсию

}

}

 

 

int main()

{

int x,firstValue,secondValue;

in>>firstValue;

in>>secondValue;

while (!in.eof())

{

in>>x;

add(x,root);

}

 

queue <int>q;

tree *firstNode=searchNode(root, firstValue);

tree *secondNode=searchNode(root, secondValue);

 

if (!firstNode) // если указатель пустой, то узел со значением а в дереве нет

out<<"вершина со значением" << firstValue<<" в дереве отсутствует";

 

else if (!secondNode) // если указатель пустой, то узел со значением b в дереве нет

out<<"вершина со значением" << secondValue<<" в дереве отсутствует";

 

else { /* в противном случае вызываем функцию, записывающую путь от узла rА до узла со значение b в очередь */

way(firstNode,secondValue,q);

 

/* если очередь не пуста, то мы нашли путь от узла со значением а

до узла со значением b и выводим его из очереди, в противном

случае путь отсутствует */

if (!q.empty())

while (!q.empty())

{

x=q.front();

q.pop();

out<<x<<"\t";

}

else out<< "путь отсутствует";

}

 

deleteTree(root);

in.close();

}

 

 

_____________________________input.txt________________________________

 

7 3

10 7 25 31 18 6 3 12 22 8

 

 

_______output.txt____________

7 6 3

 

 

_____________________________input.txt________________________________

 

7 31

10 7 25 31 18 6 3 12 22 8

 

_______output.txt____________

путь отсутствует

Замечание. Во входном файле были приведены данные, соответствующие примеру 3.

 

 

Никифорак М.В.

СЕРЕДНЬОВІЧНА ДЕРЖАВА І ПРАВО ФРАНЦІЇ

Методичні матеріали до семінарського заняття

з історії держави і права зарубіжних країн

Чернівці

“Рута”


УДК: 34 (4/9)(09)(073)

ББК: 67.2(4/8)я7

Н-627

 

 

Друкується за ухвалою редакційно-видавничої ради Чернівецького національного університету імені Юрія Федьковича

 

 

Рецензенти: Меленко С.Г., кандидат юридичних наук, доцент

Савчук С.В., кандидат юридичних наук, доцент

 

Відповідальний за випуск: Меленко С.Г., кандидат юридичних наук, доцент

 

 




Дата добавления: 2014-12-20; просмотров: 96 | Поможем написать вашу работу | Нарушение авторских прав




lektsii.net - Лекции.Нет - 2014-2025 год. (0.03 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав