powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Бинарное дерево поиска - проблема с удалением вершины
2 сообщений из 2, страница 1 из 1
Бинарное дерево поиска - проблема с удалением вершины
    #39439192
Фотография mraklbrw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый вечер.

Занимаюсь написанием класса бинарного дерева, и вот возникла проблема: затруднения с написанием функции RemoveNode - случай, когда вершина имеет два потомка. В этом случае может быть несколько вариантов - у левой дочерней вершины нет правого потомка, есть правый потомок(спускаемся по правым потомкам до последнего, у него или нет потомков или есть).

Код
Код: 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.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BinaryTree
{
        public class BinaryNode
    {
        public BinaryNode Left { get; set; } // Левое поддерево
        public BinaryNode Right { get; set; } // Правое поддеревго
        public int value { get; set; } // Числовое значение вершины
        public int level { get; set; } // Уровень дерева, на котором находится вершина

        public BinaryNode(int value)
        {
            // Констркутор вершины
            // На вход даём числовое значение вершины

            this.value = value;
            Left = null;
            Right = null;
        }

        public int GetLevel()
        {
            return level;
        }
    }
        
    public class BinaryTree
    {
        public BinaryNode node_root;
        private int count;
        private int min_value;
        private int max_value;

        public BinaryTree(BinaryNode root_node)
        {
            // Констркутор бинарного дерева
            // На вход даём корневую вершину
            this.node_root = root_node;
            this.count = 1; // Поправка на корневую вершину
        }

        public int GetNodesCount()
        {
            return count;
        }

        public int GetMinValue()
        {
            return min_value;
        }

        public int GetMaxValue()
        {
            return max_value;
        }

        public void AddElement(int new_value)
        {
            if (new_value > max_value)
                max_value = new_value;
            else if (new_value < min_value)
                min_value = new_value;

            int level = 0;

            if (node_root == null)
            {
                node_root = new BinaryNode(new_value);
                node_root.level = level;
                count++;
                return;
            }
            else
                InsertElement(node_root, new_value, level);
        }        

        public void InsertElement(BinaryNode node, int new_value, int level)
        {
            level++;
            if (new_value > node.value) // Новый элемент > элемент
            {
                // Проверяем правую ветвь
                if (node.Right == null)
                {
                    node.Right = new BinaryNode(new_value);
                    node.Right.level = level + 1;
                    count++;
                }
                else
                    InsertElement(node.Right, new_value, level);
            }
            else // Новый элемент < элемент
            {
                // Проверяем левую ветвь
                if (node.Left == null)
                {
                    node.Left = new BinaryNode(new_value);
                    node.Left.level = level + 1;
                    count++;
                }
                else
                    InsertElement(node.Left, new_value, level);
            }
        }

        public bool FindValue(BinaryNode node, int search_value)
        {
            // На вход подаём корневую вершину

            if (search_value == node.value)
                return true;
            else if (search_value < node.value)
            {
                if (node.Left == null)
                    return false;
                else
                    return FindValue(node.Left, search_value);
            }
            else if (search_value > node.value)
            {
                if (node.Right == null)
                    return false;
                else
                    return FindValue(node.Right, search_value);
            }

            return false;
        }

        public bool FindNode(BinaryNode node, int search_value, ref BinaryNode result_node)
        {
            // На вход подаём корневую вершину

            if (search_value == node.value)
            {
                result_node = node;
                return true;
            }
            else if (search_value < node.value)
            {
                if (node.Left == null)
                    return false;
                else
                    return FindNode(node.Left, search_value, ref result_node);
            }
            else if (search_value > node.value)
            {
                if (node.Right == null)
                    return false;

                else
                    return FindNode(node.Right, search_value, ref result_node);
            }

            return false;
        }

        public bool FindNodeParent(BinaryNode node, int search_value, ref BinaryNode result_node)
        {
            // На вход подаём корневую вершину

            if (node.Left != null)
            {
                if (node.Left.value == search_value)
                {
                    result_node = node;
                    return true;
                }
                if (FindNodeParent(node.Left, search_value, ref result_node))
                    return true;
            }
            if (node.Right != null)
            {
                if (node.Right.value == search_value)
                {
                    result_node = node;
                    return true;
                }
                if (FindNodeParent(node.Right, search_value, ref result_node))
                    return true;
            }

            return false;
        }

        public void TraversePreorder(BinaryNode node) // Прямой обход дерева
        {
            // На вход подаём корневую вершину

            // Здесь можем выполнять какие-нибудь действия

            MessageBox.Show(Convert.ToString(node.value));

            if (node.Left != null)
                TraversePreorder(node.Left);
            if (node.Right != null)
                TraversePreorder(node.Right);
        }

        public void TraverseInorder(BinaryNode node) // Симметричный обход дерева
        {
            // На вход подаём корневую вершину

            if (node.Left != null)
                TraversePreorder(node.Left);

            // Здесь можем выполнять какие-нибудь действия

            MessageBox.Show(Convert.ToString(node.value));

            if (node.Right != null)
                TraversePreorder(node.Right);
        }

        public void TraversePostorder(BinaryNode node) // Обход дерева в обратном порядке
        {
            // На вход подаём корневую вершину

            if (node.Left != null)
                TraversePreorder(node.Left);
            if (node.Right != null)
                TraversePreorder(node.Right);

            // Здесь можем выполнять какие-нибудь действия

            MessageBox.Show(Convert.ToString(node.value));
        }

        public void TraverseDepth(BinaryNode node) // Обход дерева в ширину
        {
            // На вход подаём корневую вершину

            Queue<BinaryNode> children = new Queue<BinaryNode>();

            children.Enqueue(node); // Помещаем корень в очередь

            while(children.Count != 0) // Пока очередь не пуста
            {
                BinaryNode nodeT = children.Dequeue(); // Берём следующую вершину из очереди

                // Здесь можем выполнять какие-нибудь действия

                MessageBox.Show(Convert.ToString(nodeT.value));

                if (nodeT.Left != null)
                    children.Enqueue(nodeT.Left);
                if (nodeT.Right != null)
                    children.Enqueue(nodeT.Right);
            }
        }



        public bool RemoveNode(int value)
        {
            BinaryNode nodeT = new BinaryNode(6666);

            if (!FindNode(node_root, value, ref nodeT)) // Не найдена вершина для удаления
                return false;
            else
            {
                if (nodeT.Left == null && nodeT.Right == null) // Терминальная вершина
                {
                    BinaryNode nodeT2 = new BinaryNode(7777);

                    FindNodeParent(node_root, nodeT.value, ref nodeT2); // Ищем родительскую вершину для удаляемой вершины

                    if (nodeT2.Left == nodeT)
                    {
                        nodeT2.Left = null;
                        count--; // Уменьшаем счётчик количества вершин в дереве
                        return true;
                    }
                    else
                    {
                        nodeT2.Right = null;
                        count--; // Уменьшаем счётчик количества вершин в дереве
                        return true;
                    }
                }
                else if (nodeT.Left != null && nodeT.Right == null) // Имеет только левого потомка
                {
                    BinaryNode nodeT3 = new BinaryNode(8888);
                    FindNodeParent(node_root, nodeT.value, ref nodeT3); // Ищем родительскую вершину для удаляемой вершины
                    nodeT3.Left = nodeT.Left;
                    count--; // Уменьшаем счётчик количества вершин в дереве
                    return true;
                }
                else if (nodeT.Left == null && nodeT.Right != null) // Имеет только правого потомка
                {
                    BinaryNode nodeT4 = new BinaryNode(9000);
                    FindNodeParent(node_root, nodeT.value, ref nodeT4); // Ищем родительскую вершину для удаляемой вершины
                    nodeT4.Right = nodeT.Right;
                    count--; // Уменьшаем счётчик количества вершин в дереве
                    return true;
                }
                else if (nodeT.Left != null && nodeT.Right != null) // Имеет левого и правого потомка
                {
                    BinaryNode nodeT5 = new BinaryNode(9001);
                    FindNodeParent(node_root, nodeT.value, ref nodeT5); // Ищем родительскую вершину для удаляемой вершины

                    if (nodeT.Left.Right == null) // Левый потомок не имеет правого потомка
                    {
                        BinaryNode nodeTT = new BinaryNode(9002);
                        nodeTT = nodeT.Right;
                        nodeT5.Left = nodeT.Left;
                        nodeT.Left.Right = nodeTT;
                        count--; // Уменьшаем счётчик количества вершин в дереве
                        return true;
                    }
                    else if (nodeT.Left.Right != null) //Левый потомок имеет правого потомка
                    {
                        BinaryNode nodeT6 = new BinaryNode(9003);
                        FindNodeParent(node_root, nodeT.value, ref nodeT6); // Ищем родительскую вершину для удаляемой вершины

                        if (nodeT.Left.Right.Right == null) // Правый потомок левого потомка не имеет правого потомка
                        {
                            if (nodeT6.Left == nodeT) // Удаляемая вершина является левым потомком родительской вершины
                            {
                                nodeT6.Left = nodeT.Left.Right.Right;
                                
                            }
                            else
                            {
                                nodeT6.Right = nodeT.Left.Right.Right;

                            }
                        }
                    }
                }
            }

            return false;
        }
            
        private void FindRightNode()
        {

        }

            

    }
}


...
Рейтинг: 0 / 0
Бинарное дерево поиска - проблема с удалением вершины
    #39439204
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mraklbrw,

согласен, разрешаю.
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Бинарное дерево поиска - проблема с удалением вершины
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]