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

ЛР3

.docx
Скачиваний:
8
Добавлен:
01.09.2021
Размер:
53.24 Кб
Скачать

МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ

федеральное государственное автономное образовательное учреждение высшего образования

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ»

КАФЕДРА № 53

ОТЧЕТ ЗАЩИЩЕН С ОЦЕНКОЙ

ПРЕПОДАВАТЕЛЬ

ассистент

М.П. Агеев

должность, уч. степень, звание

подпись, дата

инициалы, фамилия

ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ № 3

БИНАРНОЕ ДЕРЕВО

по курсу: ТЕХНОЛОГИИ ПРОГРАММИРОВАНИЯ

РАБОТУ ВЫПОЛНИЛА

СТУДЕНТКА ГР. №

подпись, дата

инициалы, фамилия

Санкт-Петербург 2021

Цель работы

Построение и изучение возможностей бинарного дерева.

Задание

Разработать программу, принимающую на вход числовую

последовательность для построения бинарного дерева. Программа должна предоставлять следующий функционал:

1. Поиск элемента в заданном дереве (макс. 5 баллов);

2. Удаление/ добавление элемента (макс. 5 баллов);

3. Графическое представление дерева (макс. 5 баллов).

Листинг программы

namespace ConsoleApp1

{

class BinaryTree

{

private TreeNode root;

public TreeNode Find(int data)

{

if (root != null) /*если root не нулевой, тогда ищем нужный узел*/

{

return root.Find(data);

}

else

{

return null;

}

}

public void Insert(int data) //добавление числа

{

if (root != null) // если root не нулевой, то добавляем

{

root.Insert(data);

}

else

{

root = new TreeNode(data); // если root нулевой, то задаем его новым узлом

}

}

public void Insert2(TreeNode ToInsert, int data) // добавление узла

{

root.Insert2(ToInsert, data);

}

public int SoftDelete(int data)

{

bool stop = false;

bool left = false;

TreeNode current = root.Find(data); // то, что хотим удалить

TreeNode parent = root; // для поиска узла-родителя

if ((parent.LeftNode != null) && (parent.RightNode != null))

{

while (!stop)

{

if ((current.Data < parent.Data) && (parent.LeftNode.Data != current.Data) && (parent.RightNode.Data != current.Data))

{

parent = parent.LeftNode;

}

else

{

if (parent.LeftNode.Data == current.Data)

{

if ((current.LeftNode == null) && (current.RightNode == null))

{

root.LeftNode = null;

return Height();

}

else

{

stop = true;

left = true;

break;

}

} else

{

if (parent.RightNode.Data == current.Data)

{

if ((current.LeftNode == null) && (current.RightNode == null))

{

root.RightNode = null;

return Height();

} else

{

stop = true;

break;

}

}

}

parent = parent.RightNode;

}

if (parent.LeftNode != null)

{

if (parent.LeftNode.Data == data)

{

stop = true;

left = true;

}

else

{

if (parent.RightNode != null)

{

if (parent.RightNode.Data == data)

{

stop = true;

}

}

}

}

}

} else

{

root = null;

}

// присоединение веток

if (left)

{

parent.LeftNode = current.RightNode;

if (current.LeftNode != null)

{

Insert2(current.LeftNode, current.LeftNode.Data);

}

return Height();

} else

{

parent.RightNode = current.RightNode;

if (current.LeftNode != null)

{

Insert2(current.LeftNode, current.LeftNode.Data);

}

return Height();

}

}

public int Height()

{

if (root == null)

{ return 0; } // если root нулевой, то и количество уровней = 0

return root.Height();

}

//private int level = -1;

public void ToList(ref List<List<int>> nodes, int x)

{

if (root != null)

{

TreeNode current = root.Find(x); //current - это текущий узел

root.ToList(current, ref nodes); // ref nodes - это указатель на list с узлами

}

}

}

public class TreeNode

{

private int data; //data - значение (само число)

public int Data

{

get { return data; }

}

private TreeNode rightNode; //узел справа снизу

public TreeNode RightNode

{

get { return rightNode; }

set { rightNode = value; }

}

private TreeNode leftNode; //узел слево снизу

public TreeNode LeftNode

{

get { return leftNode; }

set { leftNode = value; }

}

public TreeNode(int value) //конструктор самого узла

{

data = value;

}

public TreeNode Find(int value)

{

TreeNode currentNode = this; //текущий узел

while (currentNode != null) //пока не дошел до края

{

if (value == currentNode.data/* && isDeleted == false*/)

{

return currentNode; //вернет узел, когда найдет совпадение

}

else if (value > currentNode.data)

{

currentNode = currentNode.rightNode; //если значение больше, чем у текущего, то уходим вправо

}

else

{

currentNode = currentNode.leftNode; // иначе идем влево

}

}

return null; //если совпадений не найдено

}

public void Insert(int value)

{

if (value >= data)

{

if (rightNode == null)

{

rightNode = new TreeNode(value); //если значение больше и справа пусто, то ставим туда

}

else

{

rightNode.Insert(value); //если справа что-то есть, то просто переходим туда и ищем дальше

}

}

else

{

if (leftNode == null)

{

leftNode = new TreeNode(value); //если значение меньшн и слево пусто, то ставим туда

}

else

{

leftNode.Insert(value); //если слево что-то есть, то просто переходим туда и ищем дальше

}

}

}

public void Insert2(TreeNode ToInsert, int value)

{

if (value >= data)

{

if (rightNode == null)

{

rightNode = ToInsert; //если значение больше и справа пусто, то ставим туда

}

else

{

rightNode.Insert2(ToInsert ,value); //если справа что-то есть, то просто переходим туда и ищем дальше

}

}

else

{

if (leftNode == null)

{

leftNode = ToInsert; //если значение меньшн и слево пусто, то ставим туда

}

else

{

leftNode.Insert2(ToInsert, value); //если слево что-то есть, то просто переходим туда и ищем дальше

}

}

}

public int Height()

{

if (this.leftNode == null && this.rightNode == null)

{

return 1; // вернет 1, когда найдет край

}

int left = 0;

int right = 0;

if (this.leftNode != null)

left = this.leftNode.Height(); //если слево есть узел, переходим в него

if (this.rightNode != null)

right = this.rightNode.Height(); //и наоборот

if (left > right)

{

return (left + 1);

}

else

{

return (right + 1);

}

}

private int level = -1;

public void ToList(TreeNode current, ref List<List<int>> nodes)

{

level++; //отвечает за уровень, на который добавляем

nodes[level].Add(current.data); // иначе добавим просто само значение

if (current.leftNode != null)

{

ToList(current.leftNode, ref nodes);

} else nodes[level+1].Add(-2); // -2 это особое значение, вместо которого потом будет пустое окошко

if (current.rightNode != null)

{

ToList(current.rightNode, ref nodes);

} else nodes[level+1].Add(-2);

level--;

}

}

using System;

using System.Collections.Generic;

namespace ConsoleApp1

{

class Program

{

static void Main(string[] args)

{

BinaryTree binaryTree = new BinaryTree(); //создаем экземпляр бинарного дерева

List<List<int>> nodes = new List<List<int>>(); // узлы

bool first = true; //для сохранения первого элемента

int IntFirst = -1;

bool stop = false;

while (!stop)

{

Console.WriteLine($"Введите число или '-1' для выхода");

string str = Console.ReadLine();

if (str != "-1" && str.Length > 0)

{

bool stop2 = false;

for (int i = 0; i < str.Length; i++)

{

if (str[i] >= '0' && str[i] <= '9') //проверка ввода

{

} else

{

stop2 = true;

}

}

if (!stop2)

{

if (Convert.ToInt32(str) >= 0 && Convert.ToInt32(str) <= 99)

{

binaryTree.Insert(Convert.ToInt32(str)); // добавление

if (first)

{

IntFirst = Convert.ToInt32(str);

first = false;

}

}

else

{

Console.WriteLine($"Ошибка");

}

}

else

{

Console.WriteLine($"Ошибка");

}

} else

{

stop = true;

}

}

if (IntFirst != -1) //если есть хоть один элемент

{

int height = binaryTree.Height();

for (int i = 0; i < height+2; i++)

{

nodes.Add(new List<int>()); //создаем уровни

}

bool deleting = true;

bool stop3 = false;

while (deleting)

{

Console.WriteLine($"Для удаления элемента введите del иначе введите 0");

string ans = Console.ReadLine();

if (ans == "del")

{

Console.WriteLine($"Выберете элемент");

string ans2 = Console.ReadLine();

for (int i = 0; i < ans2.Length; i++)

{

if (ans2[i] >= '0' && ans2[i] <= '9') //проверка ввода

{

}

else

{

stop3 = true;

}

}

if (!stop3)

{

if (binaryTree.Find(Convert.ToInt32(ans2)) != null)

{

height = binaryTree.SoftDelete(Convert.ToInt32(ans2));

}

}

}

else

{

deleting = false;

}

}

binaryTree.ToList(ref nodes, IntFirst); /*IntFirst - первое значение а через ToList загоняем все nodes в List*/

int width = Convert.ToInt32(Math.Pow(2, height - 1)*4 - 3); //считаем ширину по самому низу

Console.WriteLine($"Вывод дерева:");

if (nodes.Count > 1)

{

for (int i = 0; i < height; i++) //идем по уровням

{

for (int j = 0; j < Math.Pow(2, i); j++)

{

for (int y = 0; y < width / Math.Pow(2, i + 1) - 1; y++)

{

Console.Write($" "); // это как раз расстояния между числами (этот перед числом)

}

if (j < nodes[i].Count && nodes[i][j] != -2)

{

if (nodes[i][j].ToString().Length > 1)

{

Console.Write($"{nodes[i][j]}"); // вывод двузначного числа

}

else

{

Console.Write($"{nodes[i][j]} "); // вывод числа с одним знаком

}

}

else

{

Console.Write($" "); // пустые места заменяются на пробелы, и под пустыми местами добавляются пробелы

nodes[i + 1].Insert(j * 2, -2);

nodes[i + 1].Insert(j * 2 + 1, -2);

}

for (int y = 0; y < width / Math.Pow(2, i + 1) - 1; y++)

{

Console.Write($" "); //(это после числа)

}

}

Console.WriteLine($""); Console.WriteLine($""); //расстояния между уровнями

}

}

} else

{

Console.WriteLine($"Значения отстуствуют");

}

}

}

}

Результат работы программы

На рисунке 1 представлен результат работы программы.

Рисунок 1 –Результат работы программы

Вывод

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

Соседние файлы в предмете Технология программирования