Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/18: Рейтинг темы: голосов - 18, средняя оценка - 4.78
0 / 0 / 0
Регистрация: 20.10.2018
Сообщений: 16

Удаление поддеревьев из двоичного дерева поиска

04.11.2018, 01:01. Показов 3727. Ответов 7

Студворк — интернет-сервис помощи студентам
Дано некоторое двоичное дерево поиска. Также даны запросы на удаление из него вершин, имеющих заданные ключи, причем вершины удаляются целиком вместе со своими поддеревьями.
После каждого запроса на удаление выведите число оставшихся вершин в дереве.
В вершинах данного дерева записаны ключи — целые числа, по модулю не превышающие 10 в 9. Гарантируется, что данное дерево является двоичным деревом поиска, в частности, для каждой вершины дерева V выполняется следующее условие:
все ключи вершин из левого поддерева меньше ключа вершины V;все ключи вершин из правого поддерева больше ключа вершины V.
Высота дерева не превосходит 25, таким образом, можно считать, что оно сбалансировано.
Формат входного файла
Входной файл содержит описание двоичного дерева и описание запросов на удаление.
В первой строке файла находится число N (1≤N≤2⋅105)— число вершин в дереве. В последующих N строках файла находятся описания вершин дерева. В (i+1)-ой строке файла (1≤i≤N) находится описание i-ой вершины, состоящее из трех чисел Ki,Li,Ri, разделенных пробелами — ключа в i-ой вершине (|Ki|≤109), номера левого ребенка i-ой вершины (i<Li≤N) или Li=0, если левого ребенка нет) и номера правого ребенка i-ой вершины (i<Ri≤N) или Ri=0, если правого ребенка нет).
Все ключи различны. Гарантируется, что данное дерево является деревом поиска.
В следующей строке находится число M(1≤M≤2⋅105)— число запросов на удаление. В следующей строке находятся M
чисел, разделенных пробелами — ключи, вершины с которыми (вместе с их поддеревьями) необходимо удалить. Все эти числа не превосходят 10 в 9 по абсолютному значению. Вершина с таким ключом не обязана существовать в дереве — в этом случае дерево изменять не требуется. Гарантируется, что корень дерева никогда не будет удален.
Формат выходного файла
Выведите
M
строк. На i-ой строке требуется вывести число вершин, оставшихся в дереве после выполнения i-го запроса на удаление.
Пример
input.txt
6
-2 0 2
8 4 3
9 0 0
3 6 5
6 0 0
0 0 0
4
6 9 7 8
output.txt
5
4
4
1
Кто может помочь реализовать решение данной задачи на C#? Я даже дерево создать по входным данным нормально не могу.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.11.2018, 01:01
Ответы с готовыми решениями:

Удаление элемента из двоичного бинарного дерева поиска
Здравствуйте! Подскажите пожалуйста, как удалить элемент из двоичного бинарного дерева поиска, если имеются как левое, так и правое...

Для каждой вершины двоичного дерева посчитать разность между количеством левых и правых поддеревьев
Помогите, пожалуйста! Такое задание:а) Построить двоичное дерево сортировки.(это вроде сделала); б)...

Реализация двоичного дерева поиска
Вот, собственно, код: #ifndef DICTIONARY_H_INCLUDED #define DICTIONARY_H_INCLUDED #include &lt;string.h&gt; typedef struct...

7
1152 / 860 / 263
Регистрация: 30.04.2009
Сообщений: 3,603
04.11.2018, 01:58
Пример входных данных неадекватный
0
0 / 0 / 0
Регистрация: 20.10.2018
Сообщений: 16
04.11.2018, 09:36  [ТС]
1 строка-число вершин дерева. Следующие 6 строк - описание вершин и их связей. Значение 1 - ключ вершины, значения 2-номер строки элемента, который является левым ребенком (0, если ребенка), 3 значение - так же для правого ребенка.
Далее число запросов удалений. И собственно значения, которые нужно удалить в самой последней строке.
0
1152 / 860 / 263
Регистрация: 30.04.2009
Сообщений: 3,603
04.11.2018, 12:26
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
    class Program
    {
        static void Main(string[] args)
        {
            (TreeNode bst, int[] keysToRemove) = ReadInputDataFromFile("e:/input.txt");
 
            foreach (var key in keysToRemove)
            {
                RemoveSubTree(bst, key);
            }
        }
 
        private static (TreeNode bst, int[] keysToRemove) ReadInputDataFromFile(string filePath)
        {
            using(var stream = File.OpenRead(filePath))
            using(var reader = new StreamReader(stream))
            {
                string nodeCountStr = reader.ReadLine();
                int nodeCount = int.Parse(nodeCountStr);
 
                TreeNode[] nodes = new TreeNode[nodeCount];
                for (int i = 0; i < nodeCount; i++)
                {
                    nodes[i] = new TreeNode();
                }
 
                for (int i = 0; i < nodeCount; i++)
                {
                    string nodeStr = reader.ReadLine();
                    string[] nodeParts = nodeStr.Split(new [] {' '}, StringSplitOptions.RemoveEmptyEntries);
                    
                    int value = int.Parse(nodeParts[0]);
                    int leftNum = int.Parse(nodeParts[1]);
                    int rightNum = int.Parse(nodeParts[2]);
                    
                    nodes[i].Value = value;
                    if (leftNum > 0)
                    {
                        nodes[i].Left = nodes[leftNum-1];
                    }
 
                    if (rightNum > 0)
                    {
                        nodes[i].Right = nodes[rightNum-1];
                    }
                }
 
                string removeNodeKeysCountStr = reader.ReadLine();
                int removeNodeKeysCount = int.Parse(removeNodeKeysCountStr);
                
                int[] removeNodeKeys = new int[removeNodeKeysCount];
                string removeNodeKeysStr = reader.ReadLine();
                string[] removeNodeKeysStrParts = removeNodeKeysStr.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);
                for (int i = 0; i < removeNodeKeysCount; i++)
                {
                    removeNodeKeys[i] = int.Parse(removeNodeKeysStrParts[i]);
                }
 
                TreeNode root = nodes[0]; // предполагаем, что в файле первый элемент дерева - корень, иначе его нужно искать, а это громоздкий алгоритм 
                return (root, removeNodeKeys);
            }
        }
 
        private static void RemoveSubTree(TreeNode bst, int subTreeKey)
        {
            if (bst == null)
            {
                return;
            }
 
            if (bst.Left?.Value == subTreeKey)
            {
                bst.Left = null;
                return;
            }
 
            if (bst.Right?.Value == subTreeKey)
            {
                bst.Right = null;
                return;
            }
 
            if (subTreeKey < bst.Value)
            {
                RemoveSubTree(bst.Left, subTreeKey);
            }
            else
            {
                RemoveSubTree(bst.Right, subTreeKey);
            }
        }
    }
 
    public class TreeNode
    {
        public int Value { get; set; }
        public TreeNode Left { get; set; }
        public TreeNode Right { get; set; }
 
        public TreeNode()
        {
        }
    }
1
0 / 0 / 0
Регистрация: 20.10.2018
Сообщений: 16
04.11.2018, 14:41  [ТС]
А как можно количество оставшихся после удаления вершин найти? Просто обойдя все дерево снова? А это не будет долгой операцией?
0
1152 / 860 / 263
Регистрация: 30.04.2009
Сообщений: 3,603
04.11.2018, 15:37
Цитата Сообщение от sthoe Посмотреть сообщение
А как можно количество оставшихся после удаления вершин найти? Просто обойдя все дерево снова?
Да

Цитата Сообщение от sthoe Посмотреть сообщение
А это не будет долгой операцией?
Это будет иметь временнyю сложность (time complexity) O(n), и для обычного дерева это единственный способ посчитать количество элементов.
Можно реализовать хранение количества элементов поддерева в каждом элементе, но тогда уменьшится скорость вставки/удаления элементов.
Тут надо понимать, что не существует идеальной структуры данных, где все типы операций (вставка, удаление, поиск по индексу, поиск по значению и т.д.) будут выполняться максимально быстро.
1
0 / 0 / 0
Регистрация: 20.10.2018
Сообщений: 16
04.11.2018, 15:53  [ТС]
А как посчитать высоту дерева?
0
1152 / 860 / 263
Регистрация: 30.04.2009
Сообщений: 3,603
04.11.2018, 17:08
Обходим дерево обычным способом, на каждый следующий уровень передаем счетчик уровня увеличенный на 1.
Рекурсивно возвращаем макс значение из двух поддеревьев (left,right). На последнем уровне возвращаем значение самого счетчика.
Вроде так.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
04.11.2018, 17:08
Помогаю со студенческими работами здесь

Определить количество уровней двоичного дерева поиска
Привет всем неравнодушным)! Напишите элемент-функцию depth, принимающую в качестве аргумента двоичное дерево и определяющую, сколько...

Сортировка файла с помощью двоичного дерева поиска
На вход подается не отсортированный файл. На выходе имеем отсортированный файл, справа от каждой строки должно быть отображено её...

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

Удаление корня двоичного дерева
двоичное дерево состоит только из ptr корень двоичного дерева как удалить этот корень?

Частотный словарь из слов текстового файла в виде дерева двоичного поиска
Задача: Построить частотный словарь из слов текстового файла в виде дерева двоичного поиска. Вывести его на экран в виде дерева....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru