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

Практика 5(СД)

.pdf
Скачиваний:
1
Добавлен:
08.10.2025
Размер:
539.88 Кб
Скачать

public TreeNode Data;

// Данные - узел дерева

public QueueNode Next;

// Следующий узел в очереди

public QueueNode(TreeNode data)

{

Data = data;

Next = null;

}

}

// Простая очередь, реализованная как связный список для обхода дерева class SimpleQueue

{

private QueueNode head;

// Голова очереди - первый элемент

private QueueNode tail;

// Хвост очереди - последний элемент

// Конструктор создает пустую очередь public SimpleQueue()

{

head = null; tail = null;

}

11

// Добавляет узел в конец очереди public void Enqueue(TreeNode data)

{

QueueNode newNode = new QueueNode(data);

if (tail == null) // Если очередь пуста, голова и хвост совпадают

{

head = tail = newNode;

}

else // Иначе вставляем в хвост и обновляем ссылку

{

tail.Next = newNode; tail = newNode;

}

}

// Удаляет и возвращает узел из головы очереди, если нет элементов -

возвращает null

public TreeNode Dequeue()

{

if (head == null) return null; TreeNode data = head.Data;

head = head.Next;

12

if (head == null) tail = null;

return data;

}

// Проверяет, пуста ли очередь public bool IsEmpty()

{

return head == null;

}

}

// Класс бинарного дерева поиска с основными методами class BinarySearchTree

{

private TreeNode root; // Корень дерева

// Конструктор инициализирует пустое дерево public BinarySearchTree()

{

root = null;

}

13

// Добавляет элемент в дерево, возвращает true если добавлен успешно (нет дубликата)

public bool AddItem(int a)

{

if (root == null)

// Если дерево пустое, создаём корень

{

 

root = new TreeNode(a); return true;

}

return AddRecursive(root, a); // Иначе рекурсивно добавляем

}

// Рекурсивный метод добавления, ищет место для нового элемента private bool AddRecursive(TreeNode node, int a)

{

if (a == node.Data)

 

return false;

// Элемент уже есть, не добавляем дубли

if (a < node.Data)

// Идём в левое поддерево

{

 

if (node.Left == null)

{

14

node.Left = new TreeNode(a); return true;

}

else

return AddRecursive(node.Left, a);

}

else // Идём в правое поддерево

{

if (node.Right == null)

{

node.Right = new TreeNode(a); return true;

}

else

return AddRecursive(node.Right, a);

}

}

// Удаляет элемент из дерева, возвращает true, если удаление произошло public bool RemoveItem(int a)

{

bool removed;

15

root = RemoveRecursive(root, a, out removed); return removed;

}

// Рекурсивное удаление элемента с поддержанием свойств дерева private TreeNode RemoveRecursive(TreeNode node, int a, out bool removed)

{

removed = false;

 

if (node == null)

 

return null;

// Элемент не найден

if (a < node.Data)

// Идём в левое поддерево

node.Left = RemoveRecursive(node.Left, a, out removed);

else if (a > node.Data)

// Идём в правое поддерево

node.Right = RemoveRecursive(node.Right, a, out removed);

else

 

{

 

removed = true;

// Элемент найден, удаляем

if (node.Left == null) // Если нет левого ребенка, возвращаем правого return node.Right;

else if (node.Right == null) // Если нет правого ребенка, возвращаем

левого

return node.Left;

16

//Если есть оба ребенка:

//Находим минимальный элемент в правом поддереве (наименьший потомок)

TreeNode minRight = FindMinNode(node.Right);

node.Data = minRight.Data; // Заменяем значение удаляемого узла

// Удаляем дубликат значения из правого поддерева

node.Right = RemoveRecursive(node.Right, minRight.Data, out _);

}

return node;

}

// Находит узел с минимальным значением в поддереве, идя влево private TreeNode FindMinNode(TreeNode node)

{

while (node.Left != null) node = node.Left;

return node;

}

// Очищает дерево (корень становится null) public void Clear()

{

root = null;

17

}

//Выводит дерево в консоль методом поиска в ширину (по уровням)

//Вывод дерева в консоль - поиск в ширину (уровень за уровнем)

public void Print()

 

{

 

if (root == null)

// Если дерево пустое, сообщаем об этом

{

 

Console.WriteLine("(empty)");

return;

}

SimpleQueue queue = new SimpleQueue(); // Создаем пустую очередь для

обхода

 

queue.Enqueue(root);

// Помещаем корень дерева в очередь

while (!queue.IsEmpty())

// Пока в очереди есть элементы

{

 

TreeNode current = queue.Dequeue(); // Извлекаем элемент из начала очереди

Console.Write(current.Data + " "); // Выводим его значение на экран

18

// Добавляем детей текущего элемента в очередь, если они существуют

if (current.Left != null) queue.Enqueue(current.Left);

if (current.Right != null) queue.Enqueue(current.Right);

}

Console.WriteLine(); // Переход на новую строку после вывода всех элементов

}

// Поиск максимального элемента в дереве public int? FindMax()

{

if (root == null) // Если дерево пустое, возвращаем null return null;

TreeNode current = root;

// Проходим по правым потомкам, так как в бинарном дереве поиска справа содержатся большие значения

while (current.Right != null) current = current.Right;

19

// Возвращаем значение самого правого узла - максимального return current.Data;

}

// Класс с меню для взаимодействия с пользователем class Program

{

static void Main()

{

BinarySearchTree bst = new BinarySearchTree();

while (true)

{

Console.WriteLine("\nМеню:");

Console.WriteLine("1. Добавить элемент");

Console.WriteLine("2. Удалить элемент");

Console.WriteLine("3. Очистить дерево"); Console.WriteLine("4. Показать дерево (поиск в ширину)"); Console.WriteLine("5. Найти максимальный элемент");

Console.WriteLine("0. Выход");

Console.Write("Ваш выбор: ");

20

Соседние файлы в предмете Структуры данных