Практики(Вариант №7) / Практическая работа №5
.odtМинистерство науки и высшего образования Российской Федерации Федеральное государственное автономное образовательное учреждение высшего образования
«ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ УПРАВЛЕНИЯ И РАДИОЭЛЕКТРОНИКИ» (ТУСУР)
Кафедра комплексной информационной безопасности электронно-вычислительных систем (КИБЭВС)
БИНАРНЫЕ ДЕРЕВЬЯ ПОИСКА Отчет по практической работе №5 по дисциплине «Структуры данных»
Студент гр.
________
__.__.2025
Принял
Преподаватель
кафедры КИБЭВС
________ Д.Р. Уразаев
__.__.2025
Задание
Реализовать бинарное дерево поиска при помощи динамических структур (классы). Предусмотреть следующие интерфейсные методы:
Инициализация пустого дерева.
Добавление элемента в дерево bool AddItem( int a) - возвращает true, если добавление прошло успешно, иначе false. Например, если такой элемент уже был в дереве - то метод вернет false.
Удаление элемента из дерева. bool RemoveItem(int a)
Очистка дерева void Clear()
Вывод дерева (используйте поиск в ширину) void Print() или string Print()
Вариант 7. Реализуйте метод, подсчитывающий высоту дерева.
Оглавление
Задание 2
Введение 4
1 ХОД РАБОТЫ 5
Заключение 12
Приложение А 13
Введение
Целью данной работы является реализация бинарного дерева поиска с использованием динамических структур (классов).
1 ХОД РАБОТЫ
AddItem: Добавляет элемент в дерево. Если дерево пустое, элемент становится корнем, иначе вызывается рекурсивная вставка (рис. 1)
Рисунок 1 — AddItem
AddRecursive: Рекурсивно находит место для нового элемента, перемещаясь влево или вправо по дереву, в зависимости от значения элемента (рис. 2)
Рисунок 2 — AddRecursive
RemoveItem: Удаляет элемент из дерева. Вызывает рекурсивную функцию для поиска и удаления узла с заданным значением (рис. 3)
Рисунок 3 — RemoveItem
RemoveItemRecursive: Рекурсивно ищет элемент для удаления, перестраивая дерево в зависимости от наличия потомков у удаляемого узла (рис. 4)
Р
исунок
4 — RemoveItemRecursive
Clear: Очищает дерево, удаляя все узлы, сбрасывая корень дерева (рис. 5)
Рисунок 5 — Clear
Print: Выводит элементы дерева в ширину, начиная с корневого узла и проходя по уровням дерева (рис. 6)
Рисунок
6 — Print
GetHeightRecursive: Высота дерева вычисляется рекурсивно как максимальная высота левого и правого поддеревьев плюс 1 для текущего узла. Пустое дерево имеет высоту 0. (рис. 7)
Рисунок 7 — GetHeightRecursive
Текстовое описание реализации поиска максимального элемента дерева:
Высота дерева — это максимальное количество ребер от корня до самого дальнего листа. Высота пустого дерева равна 0, высота дерева из одного узла равна 1.
Текстовое описание реализации удаления элемента из дерева:
Функция удаления элемента в бинарном дереве начинается с поиска узла, который нужно удалить. Если узел найден, есть несколько вариантов. Если узел — это лист (у него нет потомков), его просто удаляют. Если у узла есть один потомок (левый или правый), узел заменяется этим потомком. Если у узла два потомка, находят наименьший элемент в правом поддереве (наименьший элемент больше удаляемого узла), копируют его значение в узел, который нужно удалить, а затем удаляют этот минимальный узел. После выполнения этих действий дерево остаётся упорядоченным (рис. 9,10,11)
Р
исунок
9 — Удаление листа
Р
исунок
10 — Удаление с 1 поддеревом
Р
исунок
11 — Удаление с 2 поддеревьями
Заключение
В ходе работы было создано бинарное дерево поиска с поддержкой основных операций: добавление, удаление, очистка, вывод, поиск высоты дерева.
Приложение А
(обязательное)
Код программы
using System;
using System.Collections.Generic;
public class Node
{
public int Data { get; set; }
public Node Left { get; set; }
public Node Right { get; set; }
public Node(int data)
{
Data = data;
Left = null;
Right = null;
}
}
public class Tree
{
public Node Root { get; private set; }
public Tree()
{
Root = null;
}
// Инициализация пустого дерева
public void Initialize()
{
Root = null;
}
// Добавление элемента в дерево
public bool AddItem(int a)
{
if (Root == null)
{
Root = new Node(a);
return true;
}
return AddItemRecursive(Root, a);
}
private bool AddItemRecursive(Node node, int a)
{
if (a == node.Data)
return false;
if (a < node.Data)
{
if (node.Left == null)
{
node.Left = new Node(a);
return true;
}
else
{
return AddItemRecursive(node.Left, a);
}
}
else
{
if (node.Right == null)
{
node.Right = new Node(a);
return true;
}
else
{
return AddItemRecursive(node.Right, a);
}
}
}
// Удаление элемента из дерева
public bool RemoveItem(int a)
{
if (Root == null)
return false;
bool found = false;
Root = RemoveItemRecursive(Root, a, ref found);
return found;
}
private Node RemoveItemRecursive(Node node, int a, ref bool found)
{
if (node == null)
return null;
if (a < node.Data)
{
node.Left = RemoveItemRecursive(node.Left, a, ref found);
}
else if (a > node.Data)
{
node.Right = RemoveItemRecursive(node.Right, a, ref found);
}
else
{
found = true;
// узел с одним потомком или без потомков
if (node.Left == null)
return node.Right;
else if (node.Right == null)
return node.Left;
// узел с двумя потомками
node.Data = FindMinValue(node.Right);
node.Right = RemoveItemRecursive(node.Right, node.Data, ref found);
}
return node;
}
private int FindMinValue(Node node)
{
int minValue = node.Data;
while (node.Left != null)
{
minValue = node.Left.Data;
node = node.Left;
}
return minValue;
}
// Очистка дерева
public void Clear()
{
Root = null;
}
// Вывод дерева (поиск в ширину)
public string Print()
{
if (Root == null)
return "Дерево пустое";
List<string> result = new List<string>();
Queue<Node> queue = new Queue<Node>();
queue.Enqueue(Root);
while (queue.Count > 0)
{
Node current = queue.Dequeue();
result.Add(current.Data.ToString());
if (current.Left != null)
queue.Enqueue(current.Left);
if (current.Right != null)
queue.Enqueue(current.Right);
}
return string.Join(" ", result);
}
// Вариант 7: Метод для нахождения высоты дерева
public int GetHeight()
{
return GetHeightRecursive(Root);
}
private int GetHeightRecursive(Node node)
{
if (node == null)
return 0;
int leftHeight = GetHeightRecursive(node.Left);
int rightHeight = GetHeightRecursive(node.Right);
return Math.Max(leftHeight, rightHeight) + 1;
}
}
// Пример использования
class Program
{
static void Main()
{
Tree tree = new Tree();
// Добавление элементов
Console.WriteLine("Добавление элементов:");
Console.WriteLine($"Добавлен 5: {tree.AddItem(5)}");
Console.WriteLine($"Добавлен 3: {tree.AddItem(3)}");
Console.WriteLine($"Добавлен 7: {tree.AddItem(7)}");
Console.WriteLine($"Добавлен 2: {tree.AddItem(2)}");
Console.WriteLine($"Добавлен 4: {tree.AddItem(4)}");
Console.WriteLine($"Добавлен 6: {tree.AddItem(6)}");
Console.WriteLine($"Добавлен 8: {tree.AddItem(8)}");
Console.WriteLine($"Повторное добавление 5: {tree.AddItem(5)}");
// Вывод дерева
Console.WriteLine("\nДерево (обход в ширину):");
Console.WriteLine(tree.Print());
// Высота дерева
Console.WriteLine($"\nВысота дерева: {tree.GetHeight()}");
// Удаление элементов
Console.WriteLine("\nУдаление элементов:");
Console.WriteLine($"Удален 4: {tree.RemoveItem(4)}");
Console.WriteLine($"Удален 10 (не существует): {tree.RemoveItem(10)}");
// Вывод после удаления
Console.WriteLine("\nДерево после удаления:");
Console.WriteLine(tree.Print());
Console.WriteLine($"Высота дерева: {tree.GetHeight()}");
// Очистка дерева
tree.Clear();
Console.WriteLine("\nПосле очистки:");
Console.WriteLine(tree.Print());
Console.WriteLine($"Высота дерева: {tree.GetHeight()}");
}
}
Томск 2025
