Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.70/30: Рейтинг темы: голосов - 30, средняя оценка - 4.70
1 / 1 / 0
Регистрация: 25.11.2014
Сообщений: 80

Заполнение бинарного дерева в ширину без очереди

08.09.2018, 22:21. Показов 7093. Ответов 60

Студворк — интернет-сервис помощи студентам
Подскажите алгоритм заполнения бинарного дерева и поиск по нему, все в ширину.

Дерево имеет такую структуру.

C#
1
2
3
4
5
6
7
8
public class MyTree
    {
        public long? Data { get; private set; }
        public MyTree Left { get; set; }
        public MyTree Right { get; set; }
        public MyTree Parent { get; set; }
        public long Count { get; private set; }
    }
Хотелось бы реализовать рекурсией без очередей и реализации базовых интерфейсов.
Такое возможно?
Заранее спасибо!
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
08.09.2018, 22:21
Ответы с готовыми решениями:

Заполнение бинарного дерева по уровням (в ширину)
Добрый день, необходимо реализовать на php заполнение бинарного дерева в ширину (первый элемент добавляется на первый уровень, второй и...

Обход бинарного дерева в ширину
Честное слово, облазил весь интернет и не нашел не одной реально рабочей программы. Сама задача вот: программа, выполняющая обход дерева...

Реализация заполнения бинарного дерева в ширину
Добрый день, есть такая задача Алгоритм нашел: Попытался написать код, но не пойму как в итоге получить само результирующее дерево?...

60
1 / 1 / 0
Регистрация: 25.11.2014
Сообщений: 80
09.09.2018, 01:02  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Если сейчас не нужно - лучше уберите. Меньше ошибок будет.
Я всё на сегодня. Спок ночи!
Спасибо огромное! Буду разбираться.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
09.09.2018, 11:21
Как говорится "Утро вечера мудренее".
С утра понял, что неверно в принципе всё реализовано. Должно быть разделение классов общего объекта "MyTree" и узлов "Node". MyTree - владеет информацией обо всем дереве, иначе не организовать "поиск", "удаление" и т.д. Node - информацией только о родительском и дочерних узлах.
Это типа XDocument и XElement для работы с XML данными.
Вся информация хранится в MyTree. А Node вытаскивает из MyTree только нужную часть, инкапсулируя остальную информацию.
2
1 / 1 / 0
Регистрация: 25.11.2014
Сообщений: 80
09.09.2018, 11:35  [ТС]
Элд Хасп,
Добрый день.
Подскажите, получится реализовать добавление в ширину, не меняя структуры
C#
1
2
3
4
5
6
7
8
public class MyTree
    {
        public long? Data { get; private set; }
        public MyTree Left { get; set; }
        public MyTree Right { get; set; }
        public MyTree Parent { get; set; }
        public long Count { get; private set; }
    }
на такую
C#
1
2
3
4
5
6
7
8
9
10
 /// <summary>Данные</summary>
            public long? Data { get; private set; }
            /// <summary>Левая ветка</summary>
            public Branch Left { get; private set; }
            /// <summary>Правая ветка</summary>
            public Branch Right { get; private set; }
            /// <summary>Родительский элемент </summary>
            public MyTree Parent { get; private set; }
            /// <summary>Уровень вложения</summary>
            public long Level { get; private set; }
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
09.09.2018, 13:56
Цитата Сообщение от fivebits_ Посмотреть сообщение
Подскажите, получится реализовать добавление в ширину, не меняя структуры
Не совсем понял. Вроде в моём примере именно такая структура (с комментарием и Level вместо Count ).

Добавлено через 55 секунд
Или Вы, напротив, интересуетесь переходом на первоначальный вид?
0
1 / 1 / 0
Регистрация: 25.11.2014
Сообщений: 80
09.09.2018, 14:10  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Или Вы, напротив, интересуетесь переходом на первоначальный вид?
Да, без вложенных классов, только у меня все время стек переполнялся(логика не павильонная)

Добавлено через 9 минут
Элд Хасп,
Curry писал свой вариант, он работает и искать по нему можно, только заполняет немного не так.

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
static void MyTreeFill(List<MyTree> prev, int MaxLevel)
        {
            long lvl = prev.First().Count + 1;
            if (lvl > MaxLevel)
                return;
            
            long d = prev.Last().Data ?? 0;
            List<MyTree> next = new List<MyTree>();
            foreach (var b in prev)
            {
                MyTree l = new MyTree(++d ,lvl);
                l.Parent = b;
                MyTree r = new MyTree(++d, lvl);
                r.Parent = b;
                b.Left = l;
                b.Right = r;
                next.Add(l);
                next.Add(r);
            }
            MyTreeFill(next, MaxLevel);
        }
 
        static void Main(string[] args)
        {
            
 
            MyTree root = new MyTree(1, 1);
            List<MyTree> rootList = new List<MyTree>();
            rootList.Add(root);
            MyTreeFill(rootList, 3);
            BinaryTreeExtensions.Print(root);
            
            Console.ReadLine();
                
        }
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
09.09.2018, 14:16
Что хранит Count? Общее количество элементов в ветвях или только в данном узле?
0
1 / 1 / 0
Регистрация: 25.11.2014
Сообщений: 80
09.09.2018, 14:28  [ТС]
Цитата Сообщение от КОП Посмотреть сообщение
Что хранит Count? Общее количество элементов в ветвях или только в данном узле?
Кол-во предков
т.е. у каждого node будет
C#
1
node.Count = node.Parent.Count +1;
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
09.09.2018, 14:34
Класс Branch ввел только для удобства и инкапсуляции свойства Coun - число элементов в ветви.
Можно эти свойства вынести в основной класс.
В основном классе имя свойства Coun - заменено на Level, т.к. название не соответствует смыслу. Count - количество, Level - уровень.
Если убрать класс Branch, то свойства MyTree будут выглядеть так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
            /// <summary>Данные</summary>
            public long Data { get; private set; }
            /// <summary>Левая ветка</summary>
            public MyTree Left { get; private set; }
            /// <summary>Количество элементов в левой ветке</summary>
            public long LeftCount { get; private set; }
            /// <summary>Правая ветка</summary>
            public MyTree Right { get; private set; }
            /// <summary>Количество элементов в правой ветке</summary>
            public long RightCount { get; private set; }
            /// <summary>Родительский элемент </summary>
            public MyTree Parent { get; private set; }
            /// <summary>Уровень вложения</summary>
            public long Level { get; private set; }
Добавлено через 2 минуты
Также надо часть кода отвечающего за подсчёт элементов в ветке в методе Add класса Branch перенести в метод Add класса Branch. Справитесь?
0
1 / 1 / 0
Регистрация: 25.11.2014
Сообщений: 80
09.09.2018, 14:38  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
акже надо часть кода отвечающего за подсчёт элементов в ветке в методе Add класса Branch перенести в метод Add класса Branch. Справитесь?
Честно говоря запутался уже. Но сейчас попробую.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
09.09.2018, 14:44
Цитата Сообщение от fivebits_ Посмотреть сообщение
Curry писал свой вариант, он работает и искать по нему можно, только заполняет немного не так
Такие вопросы:
  • Будут ли методы удаления элементов?
  • Какое поведение должно быть при удалении элементов? Т.е. как перестраивать нижестоящие по уровню элементы?
  • Будут ли методы поиска?
  • Что должны возвращать методы поиска? Т.е. каким образом адресовать элементы в общем дереве? Или будет достаточно вернуть сам элемент?

Добавлено через 1 минуту
Цитата Сообщение от fivebits_ Посмотреть сообщение
Честно говоря запутался уже. Но сейчас попробую.
Вы по какому варианту собираете приложение? Если по моему - я могу сам переделать.

Добавлено через 1 минуту
Цитата Сообщение от fivebits_ Посмотреть сообщение
Да, без вложенных классов, только у меня все время стек переполнялся(логика не павильонная)
Я всё таки склоняюсь к более системному подходу - отделению класса узлов от класса дерева.
0
1 / 1 / 0
Регистрация: 25.11.2014
Сообщений: 80
09.09.2018, 14:50  [ТС]
Элд Хасп,
1)Удаление не будет.
2) Поиск должен возвращать MyTree, чтобы можно было получить тот же Level узла
Собираю по вашему варианту, главное чтобы числа,которые буду передавать писались в ширину

Добавлено через 1 минуту
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Я всё таки склоняюсь к более системному подходу - отделению класса узлов от класса дерева.
А при выводе мы же не сможем обратиться к узлу, чтобы родителя допустим получить, он будет закрыт?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
09.09.2018, 14:51
Если ни чё не напутал
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
        /// <summary>Класс бинарного дерева</summary>
        public class MyTree
        {
 
            /// <summary>Данные</summary>
            public long Data { get; private set; }
            /// <summary>Левая ветка</summary>
            public MyTree Left { get; private set; }
            /// <summary>Количество элементов в левой ветке</summary>
            public long LeftCount { get; private set; }
            /// <summary>Правая ветка</summary>
            public MyTree Right { get; private set; }
            /// <summary>Количество элементов в правой ветке</summary>
            public long RightCount { get; private set; }
            /// <summary>Родительский элемент </summary>
            public MyTree Parent { get; private set; }
            /// <summary>Уровень вложения</summary>
            public long Level { get; private set; }
 
            /// <summary>Конструктор без параметров</summary>
            private MyTree() { }
 
            /// <summary>Конструктор</summary>
            /// <param name="Data">Данные</param>
            public MyTree(long Data) => this.Data = Data;
 
            /// <summary>Добавление нового элемента в дерево</summary>
            /// <param name="NewMyTree">Новый элемент</param>
            public void Add(MyTree NewMyTree)
            {
                if (Left == null)
                {
                    NewMyTree.Parent = this;
                    NewMyTree.Level = Level + 1;
                    Left = NewMyTree;
                    LeftCount++;
                }
                else if (Right == null)
                {
                    NewMyTree.Parent = this;
                    NewMyTree.Level = Level + 1;
                    Right = NewMyTree;
                    RightCount++;
                }
                else if (LeftCount <= RightCount)
                {
                    Left.Add(NewMyTree);
                    LeftCount++;
                }
                else
                {
                    Right.Add(NewMyTree);
                    RightCount++;
                }
            }
 
            /// <summary>Создание и добавление нового элемента в дерево</summary>
            /// <param name="NewMyTree">Новый элемент</param>
            public void Add(long NewData)
            {
                Add(new MyTree(NewData));
            }
 
            /// <summary>Добавление списка новых элементов в дерево</summary>
            /// <param name="NewMyTree">Список новых данных</param>
            public void Add(List<long> ListData)
            {
                foreach (long data in ListData)
                { Add(data); }
            }
 
            /// <summary>Создание нового дерева из списка элементов</summary>
            /// <param name="ListData">Список новых данных</param>
            public static MyTree Create(List<long> ListData)
            {
                MyTree myTree = new MyTree(ListData.ElementAt(0));
                myTree.Add(ListData.GetRange(1, ListData.Count - 1));
                return myTree;
            }
 
        }
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
09.09.2018, 14:53
Цитата Сообщение от fivebits_ Посмотреть сообщение
Кол-во предков
т.е. у каждого node будет
тогда это depth, но никак не count

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Будут ли методы удаления элементов?
добавить всегда можно, вопрос лишь как должен выглядеть результат

Цитата Сообщение от Элд Хасп Посмотреть сообщение
отделению класса узлов от класса дерева.
и правильно. вот пример для заполнения.
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
    public class Node
    {
        public Node Left;
 
        public Node Right;
 
        public Node Parent;
 
        public long Value;
        
        // Всего элементов ниже
        public int Count { get; set; }
 
        public Node(long data, Node parent)
        {
            this.Value = data;
            this.Parent = parent;
            this.Count = 1;
        }
    }
 
    public class MyTree
    {
        public Node Root;
 
        public void Add(long data)
        {
            if (Root == null)
            {
                Root = new Node(data, null);
                return;
            }
 
            AddRec(data, Root);
        }
 
        private void AddRec(long data, Node parent)
        {
            parent.Count++;
            if (parent.Left == null)
            {
                parent.Left = new Node(data, parent);
                return;
            }
            if (parent.Right == null)
            {
                parent.Right = new Node(data, parent);
                return;
            }
 
            if (parent.Left.Count > parent.Right.Count && ((parent.Left.Count & parent.Left.Count + 1)) == 0)
            {
                AddRec(data, parent.Right);
                return;
            }
            AddRec(data, parent.Left);
        }
    }
 
    internal class Program
    {
        private static void Main(string[] args)
        {
            var t = new MyTree();
            for (var i = 1; i < 20; i++) t.Add(i);
            Console.ReadLine();
        }
    }
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
09.09.2018, 14:54
Цитата Сообщение от fivebits_ Посмотреть сообщение
А при выводе мы же не сможем обратиться к узлу, чтобы родителя допустим получить, он будет закрыт?
Узел Родитель так же будет доступен и будет дополнительная ссылка на всё дерево. Появится свойство - Index элемента.
0
1 / 1 / 0
Регистрация: 25.11.2014
Сообщений: 80
09.09.2018, 15:29  [ТС]
Элд Хасп,
Элд Хасп,
ROOT:1
Left for 1 --> 2
Left for 2 --> 4
Right for 2 --> 6
Right for 1 --> 3
Left for 3 --> 5
Right for 3 --> 7

Только получается 6 и 5 местами путает и так далее через 1 уровень
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
09.09.2018, 15:34
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
/// <summary>Класс бинарного дерева</summary>
    public class TreeClass
    {
        List<NodeClass> ListNode = new List<NodeClass>();
 
        /// <summary>Метод - возвращает индекс узла в общем массиве дерева</summary>
        /// <param name="Node">Узел в дереве</param>
        public int IndexOf(NodeClass Node) => ListNode.IndexOf(Node) + 1;
 
        /// <summary>Метод - возвращает по индексу узел в общем массиве дерева</summary>
        /// <param name="Node">Индекс узла</param>
        public NodeClass ElementAt(int Index) => ListNode.ElementAt(Index + 1);
 
        /// <summary>Метод - возвращает общее количество узлов в массиве дерева</summary>
        public int Count() => ListNode.Count;
 
        /// <summary>Метод - добавления узла в общий массив дерева</summary>
        /// <param name="ListData">Узел для дерева</param>
        public void Add(NodeClass Node) => ListNode.Add(Node);
 
        /// <summary>Метод - создающий новый узел в общем массиве дерева</summary>
        /// <param name="Data">Данные для нового узла</param>
        public void Add(long Data) => ListNode.Add(new NodeClass(Data));
 
        /// <summary>Метод - корневой узел массива дерева</summary>
        public NodeClass Root() => ListNode.ElementAt(0);
    }
 
    /// <summary>Класс узла бинарного дерева</summary>
    public class NodeClass
    {
        /// <summary>Данные</summary>
        public long Data { get; private set; }
        /// <summary>Левая ветка</summary>
        public NodeClass Left()
        {
            int Ind = Index() << 1;
            if (Ind > Tree.Count()) return null;
            else return Tree.ElementAt(Ind);
        }
        /// <summary>Правая ветка</summary>
        public NodeClass Right()
        {
            int Ind = (Index() << 1) + 1;
            if (Ind > Tree.Count()) return null;
            else return Tree.ElementAt(Ind);
        }
        /// <summary>Родительский элемент </summary>
        public NodeClass Parent => Tree.ElementAt(Index() >> 1);
        /// <summary>Родительское дерево</summary>
        public TreeClass Tree { get; private set; }
        /// <summary>Индекс элемента в общем массиве родительского дереве (начинается с 1)</summary>
        public int Index() => Tree.IndexOf(this);
        /// <summary>Уровень вложения</summary>
        public long Level { get; private set; }
 
        /// <summary>Конструктор без параметров</summary>
        private NodeClass() { }
 
        /// <summary>Конструктор</summary>
        /// <param name="Data">Данные</param>
        public NodeClass(long Data) => this.Data = Data;
    }
Добавлено через 18 секунд
Пока не проверял.
0
1 / 1 / 0
Регистрация: 25.11.2014
Сообщений: 80
09.09.2018, 15:43  [ТС]
КОП, А как в Вашем примере вывод сделать и поиск?
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
09.09.2018, 16:35
Цитата Сообщение от fivebits_ Посмотреть сообщение
А как в Вашем примере вывод сделать и поиск?
так как мне лень писать рекурсию, вот поиск по индексу. Для поиска по значеню можно тупо перебирать по индексу от 0 до root.Count и сравнивать.

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
    public class MyTree
    {
        public Node Root;
 
        public Node GetAt(int idx)
        {
            var curr = Root;
            foreach (bool left in getPath(idx))
            {
                if (curr == null) return curr;
                curr = left ? curr.Left : curr.Right;
            }
 
            return curr;
        }
 
        private bool[] getPath(int idx)
        {
            return Convert.ToString(idx, 2).TrimStart('0').Skip(1).Select(c => c == '0').ToArray();
        }
 
...
 
private static void Main(string[] args)
        {
            var t = new MyTree();
            for (var i = 1; i < 18; i++) t.Add(i);
            for (var i = 1; i < 20; i++) Console.WriteLine(t.GetAt(i)?.Value);
            Console.ReadLine();
        }
остальное сами
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
09.09.2018, 18:38
Лучший ответ Сообщение было отмечено fivebits_ как решение

Решение

Воскресенье - домашние заботы.
Вот так, вроде, нормально работает
Кликните здесь для просмотра всего текста
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
    class Program
    {
        static void Main(string[] args)
        {
            TreeClass myTree = new TreeClass();
 
            for (int Ind = 0; Ind <= 15; Ind++)
            {
                myTree.Add(Ind);
            }
 
            for (int Ind = 1; Ind <= myTree.Count(); Ind++)
            {
                NodeClass Node = myTree.ElementAt(Ind);
                Console.Write($"Data {Node.Data}");
                Console.Write($", Index {Node.Index}");
                Console.Write($", Level {Node.Level}");
                Console.Write($", Parent {Node.Parent?.Data }");
                Console.Write($", Left {Node.Left?.Data}");
                Console.WriteLine($", Right {Node.Right?.Data}");
            }
 
 
        }
 
    }
 
    /// <summary>Класс бинарного дерева</summary>
    public class TreeClass
    {
        List<NodeClass> ListNode = new List<NodeClass>();
 
        /// <summary>Метод - возвращает индекс узла в общем массиве дерева</summary>
        /// <param name="Node">Узел в дереве</param>
        public int IndexOf(NodeClass Node) => ListNode.IndexOf(Node) + 1;
 
        /// <summary>Метод - возвращает по индексу узел в общем массиве дерева</summary>
        /// <param name="Node">Индекс узла</param>
        public NodeClass ElementAt(int Index)
        {
            if (Index < 1 || Index > Count()) return null;
            else return ListNode.ElementAt(Index - 1);
        }
 
        /// <summary>Метод - возвращает общее количество узлов в массиве дерева</summary>
        public int Count() => ListNode.Count;
 
        /// <summary>Метод - добавления узла в общий массив дерева</summary>
        /// <param name="ListData">Узел для дерева</param>
        public void Add(NodeClass Node)
        {
            Node.Tree = this;
            ListNode.Add(Node);
        }
 
        /// <summary>Метод - создающий новый узел в общем массиве дерева</summary>
        /// <param name="Data">Данные для нового узла</param>
        public void Add(long Data) => Add(new NodeClass(Data));
 
        /// <summary>Метод - корневой узел массива дерева</summary>
        public NodeClass Root() => ListNode.ElementAt(0);
    }
 
    /// <summary>Класс узла бинарного дерева</summary>
    public class NodeClass
    {
        /// <summary>Данные</summary>
        public long Data { get; private set; }
        /// <summary>Левая ветка</summary>
        public NodeClass Left
        {
            get
            {
                int Ind = Index << 1;
                if (Ind > Tree.Count()) return null;
                else return Tree.ElementAt(Ind);
            }
        }
        /// <summary>Правая ветка</summary>
        public NodeClass Right
        {
            get
            {
                int Ind = (Index << 1) + 1;
                if (Ind > Tree.Count()) return null;
                else return Tree.ElementAt(Ind);
            }
        }
        /// <summary>Родительский элемент </summary>
        public NodeClass Parent => Tree.ElementAt(Index >> 1);
        /// <summary>Родительское дерево</summary>
        public TreeClass Tree { get; set; }
        /// <summary>Индекс элемента в общем массиве родительского дереве (начинается с 1)</summary>
        public int Index => Tree.IndexOf(this);
        /// <summary>Уровень вложения</summary>
        public int Level => (int)Math.Floor((Math.Log(Index) / Math.Log(2)));
 
        /// <summary>Конструктор без параметров</summary>
        private NodeClass() { }
 
        /// <summary>Конструктор</summary>
        /// <param name="Data">Данные</param>
        public NodeClass(long Data) => this.Data = Data;
    }


Добавлено через 1 час 16 минут
Добавил в класс Tree методы поиска по данным узла Find и индекса FindIndex. В класс Node - метод печати Print.
Кликните здесь для просмотра всего текста
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
    class Program
    {
        static void Main(string[] args)
        {
            TreeClass myTree = new TreeClass();
 
            for (int Ind = 0; Ind <= 15; Ind++)
            {
                myTree.Add(Ind);
            }
 
            for (int Ind = 1; Ind <= myTree.Count(); Ind++)
            {
                 myTree.ElementAt(Ind).Print();
            }
 
            int data = 10;
            Console.WriteLine();
            Console.WriteLine($"Поиск узла с данными = {data} - индекс узла {myTree.FindIndex(data)}");
            Console.WriteLine("Данные найденного узла" );
            myTree.Find(data).Print();
 
        }
 
    }
 
    /// <summary>Класс бинарного дерева</summary>
    public class TreeClass
    {
        List<NodeClass> ListNode = new List<NodeClass>();
 
        /// <summary>Метод - возвращает индекс узла в общем массиве дерева</summary>
        /// <param name="Node">Узел в дереве</param>
        public int IndexOf(NodeClass Node) => ListNode.IndexOf(Node) + 1;
 
        /// <summary>Метод - возвращает узел содержащий заданные данные</summary>
        /// <param name="Data">Искомые данные</param>
        public NodeClass Find(int Data) => ListNode.Find(Node => Node.Data == Data);
 
        /// <summary>Метод - возвращает индекс узла содержащий заданные данные</summary>
        /// <param name="Data">Искомые данные</param>
        public int FindIndex(int Data) => ListNode.FindIndex(Node => Node.Data == Data) + 1;
 
        /// <summary>Метод - возвращает по индексу узел в общем массиве дерева</summary>
        /// <param name="Index">Индекс узла</param>
        public NodeClass ElementAt(int Index)
        {
            if (Index < 1 || Index > Count()) return null;
            else return ListNode.ElementAt(Index - 1);
        }
 
        /// <summary>Метод - возвращает общее количество узлов в массиве дерева</summary>
        public int Count() => ListNode.Count;
 
        /// <summary>Метод - добавления узла в общий массив дерева</summary>
        /// <param name="Node">Узел для дерева</param>
        public void Add(NodeClass Node)
        {
            Node.Tree = this;
            ListNode.Add(Node);
        }
 
        /// <summary>Метод - создающий новый узел в общем массиве дерева</summary>
        /// <param name="Data">Данные для нового узла</param>
        public void Add(long Data) => Add(new NodeClass(Data));
 
        /// <summary>Метод - возвращает корневой узел массива дерева</summary>
        public NodeClass Root() => ListNode.ElementAt(0);
    }
 
    /// <summary>Класс узла бинарного дерева</summary>
    public class NodeClass
    {
        /// <summary>Данные</summary>
        public long Data { get; private set; }
        /// <summary>Левая ветка</summary>
        public NodeClass Left
        {
            get
            {
                int Ind = Index << 1;
                if (Ind > Tree.Count()) return null;
                else return Tree.ElementAt(Ind);
            }
        }
        /// <summary>Правая ветка</summary>
        public NodeClass Right
        {
            get
            {
                int Ind = (Index << 1) + 1;
                if (Ind > Tree.Count()) return null;
                else return Tree.ElementAt(Ind);
            }
        }
        /// <summary>Родительский узел </summary>
        public NodeClass Parent => Tree.ElementAt(Index >> 1);
        /// <summary>Родительское дерево</summary>
        public TreeClass Tree { get; set; }
        /// <summary>Индекс элемента в общем массиве родительского дереве (начинается с 1)</summary>
        public int Index => Tree.IndexOf(this);
        /// <summary>Уровень вложения</summary>
        public int Level => (int)Math.Floor((Math.Log(Index) / Math.Log(2)));
 
        /// <summary>Конструктор без параметров</summary>
        private NodeClass() { }
 
        /// <summary>Конструктор</summary>
        /// <param name="Data">Данные</param>
        public NodeClass(long Data) => this.Data = Data;
 
        /// <summary>Метод - вывод на консоль данных узла</summary>
        public void Print()
        {
            Console.Write($"Data {Data}");
            Console.Write($", Index {Index}");
            Console.Write($", Level {Level}");
            Console.Write($", Parent {Parent?.Data }");
            Console.Write($", Left {Left?.Data}");
            Console.WriteLine($", Right {Right?.Data}");
        }
    }
1
1 / 1 / 0
Регистрация: 25.11.2014
Сообщений: 80
09.09.2018, 18:48  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Воскресенье - домашние заботы.
Вот так, вроде, нормально работает
Если после поиска обратиться к значению родителя, то вылетает null.
Как-то странно, при выводе все ок, вывод на поиске основан.
C#
1
myTree.ElementAt(5).Parent.Data
Добавлено через 9 минут
Элд Хасп, Find работает как надо, спасибо!!!! Буду разбираться в мелочах.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
09.09.2018, 18:48

Реализовать обход бинарного дерева в ширину
необходимо реализовать обход вот этого бинарного дерева в ширину using System; using System.Collections.Generic; using System.Linq; ...

Печать на консоль бинарного дерева, обход в ширину
Добрый вечер! Сразу скажу, топик не для слабонерных. Выручайте уважаемые программисты. Встала задача передо мной написать печать на КОНСОЛЬ...

Реализация обхода в ширину и глубину бинарного дерева
Как реализовать обход дерева (глубины три, т.е. трех уровневое) в глубину и ширину и что под этим подразумевается?

Печать на консоль бинарного дерева, обход в ширину
Добрый вечер! Сразу скажу, топик не для слабонерных. Выручайте уважаемые программисты. Встала задача передо мной написать печать на КОНСОЛЬ...

Заполнение особого бинарного дерева
Собственно класс бинарного дерева я прописал (хоть и криво, не в этом дело). Но метод вставки не подходит к поставленной задачи. А именно:...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2. Задача: Обеспечить запись документа в регистр сведений независимо от. . .
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml, в чате форсили функторы модулей как суперфичу. Пытаясь отдуплить концепт, наткнулся на тутор с простым примером. А главный принцип обучения от. . .
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru