Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание специфического дерева, C# 
:(
    Опции темы
Cybernetic10
Дата 17.8.2009, 10:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 5.5.2009

Репутация: нет
Всего: нет



Нужно создать дерево, причем вершина должна смотреть на своего родителя, а так же на список своих детей.
После С++ я написал вот такую структур:

struct Node
{
/*
какие то мои данные в вершине
*/
  public Node* parent;
  public List<Node>* child;
}

Но нифига не заработало. Сначала студия попросила поставить спецификатор к указателям unsafe и позволить ей копмилировать неверифицируемый код, включив параметр /unsafe.
Сделал. Но и это не помогло. Ошибка такая:
Cannot take the address of, get the size of, or declare a pointer to a managed type ('SequentialDecoding.Node').

Собсно, вопрос. А правильно ли я вообще пытаюсь создать дерево? Можно ли как то по другому в шарпе работать с указателями, и правильно ли я вообще работаю с ними в данном контексте?

PM MAIL   Вверх
ДобренькийПапаша
Дата 17.8.2009, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 14.1.2006
Где: г.Москва

Репутация: нет
Всего: 7



А зачем вы вообще пытаетесь работать с указателями? В C# у компонента TreeNode огромное количество методов и свойств...

currentNode.Parent - родительский узел,
currentNode.Nodes - коллекция подузлов текущего узла...

Это сообщение отредактировал(а) ДобренькийПапаша - 17.8.2009, 11:10


--------------------
Меня зовут Себастьян Парейра, торговец чёрным деревом.
PM MAIL   Вверх
Cybernetic10
Дата 17.8.2009, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 5.5.2009

Репутация: нет
Всего: нет



Цитата(ДобренькийПапаша @ 17.8.2009,  11:08)
А зачем вы вообще пытаетесь работать с указателями? В C# у компонента TreeNode огромное количество методов и свойств...

Да чтоб я знал про эту компоненту smile
Сейчас почитаю о ней в МСДН

Это сообщение отредактировал(а) Cybernetic10 - 17.8.2009, 11:10
PM MAIL   Вверх
ДобренькийПапаша
Дата 17.8.2009, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 14.1.2006
Где: г.Москва

Репутация: нет
Всего: 7



Я написал свойства вам нужные, гляньте ещё раз))) я просто пост редактил)))


--------------------
Меня зовут Себастьян Парейра, торговец чёрным деревом.
PM MAIL   Вверх
Cybernetic10
Дата 17.8.2009, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 5.5.2009

Репутация: нет
Всего: нет



Что-то в консольном приложении глухо с пространством имен System.Wndows.Forms,  и соответственно с классом TreeNode.
Как мне увидеть данное пространство?
И ничего, что мое дерево никоим образом не будет работать с окнами?
PM MAIL   Вверх
ДобренькийПапаша
Дата 17.8.2009, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 14.1.2006
Где: г.Москва

Репутация: нет
Всего: 7



Цитата(Cybernetic10 @ 17.8.2009,  11:23)
И ничего, что мое дерево никоим образом не будет работать с окнами?

чего... Так работать не будет)))

Что-то я не припомню, чтобы я видел деревья в консолях (хотя наверно такое есть)...


--------------------
Меня зовут Себастьян Парейра, торговец чёрным деревом.
PM MAIL   Вверх
Cybernetic10
Дата 17.8.2009, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 5.5.2009

Репутация: нет
Всего: нет



Цитата(ДобренькийПапаша @ 17.8.2009,  11:37)
Цитата(Cybernetic10 @ 17.8.2009,  11:23)
И ничего, что мое дерево никоим образом не будет работать с окнами?

чего... Так работать не будет)))

Что-то я не припомню, чтобы я видел деревья в консолях (хотя наверно такое есть)...

Ну, мне просто нужна специфическая такая структура для хранения данных и быстрого поиска. И нафик всякие окна.

Тогда как быть с указателями, если TreeNode не юзать?
PM MAIL   Вверх
neutrino
Дата 17.8.2009, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Gothic soul
****


Профиль
Группа: Модератор
Сообщений: 3041
Регистрация: 25.3.2002
Где: Верхняя Галилея, Кармиэль

Репутация: 3
Всего: 62



Код

public class TreeNode
{
public string Name {get; set;}
public TreeNode Parent {get; set}
public ICollection<TreeNode> Children {get; set;}

public override string ToString()
{
var subTree = new StringBuilder(Name);
if (children != null & children.Count > 0)
{
subTree.Append(": {");
foreach (var child in Children)
{
subTree.Append(child.ToString() + ",");
}
subTree.Append("}");
}
return subTree.ToString();
}

}

...
TreeNode avraam = new TreeNode {Name = "Avraam"};
TreeNode itshak = new TreeNode(Name = "Itshak"};
TreeNode yaakov = new TreeNode(Name = "Yaakov"};
TreeNode ishmael = new TreeNode(Name = "Ishmael"};

avraam.Parent = null; // God :)
avraam.Children = new List<TreeNode>() {itshak, ishmael};
ishmael.Parent = avraam;
itshak.Parent = avraam;
itshak.Children = new List<TreeNode>() {yaakov};
yaakov.Parent = itshak;

Console.WriteLine(avraam);



Добавлено через 2 минуты и 35 секунд
Я этo навскидку написал. Может не компилится. Должно вывести дерево Авраама в таком виде:
Цитата

Avraam: {Itshak: {Yaakov}, Ishmael}




--------------------
The truth comes from within ...

Покойся с миром, Vit 
PM MAIL WWW ICQ Skype GTalk   Вверх
diadiavova
Дата 17.8.2009, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



neutrino, при таком подходе возможны следующие неприятности:
Коллекция, вкоторой находится узел, не согласована со свойством Parent, а стало быть существует возможность, что узел будет в одной коллекции, а свойство парент вернёт совсем другого родителя.
Коллекция List может содержать элементы, уже находящиеся в других таких же коллекциях, в результате один и тот же узел может оказаться потомком сразу нескольких узлов.

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

Лучше сделать примерно так. На тесте вроде всё работает правильно smile 
Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CustomTree
{
    class Program
    {
        static void Main(string[] args)
        {
            var root = new Node("root");
            var c1 = root.AddNode("child1");
            var c2 = root.AddNode("child2");
            var c1_1 = c1.AddNode("child1_1");
            var c1_2 = c1.AddNode("child1_2");
            var c2_1 = new Node("child2_1");
            c2_1.Parent = c2;
            var c2_2 = c2.AddNode("child2_2");
            Console.Write(root.ToString());
            Console.WriteLine("\n");
            Console.WriteLine("Удаляем узлы\n");
            c2.Children.Remove(c2_2);
            c2_1.Parent=null;
            Console.WriteLine(root.ToString());
            Console.ReadKey();
        }
    }

    public class Node
    {
        public Node()
        {
            _children = new NodeCollection(this);
        }
        public Node(string name)
        {
            _children = new NodeCollection(this);
            this.Name = name;
        }

        public Node AddNode(string name)
        {
            var rv = new Node(name);
            this.Children.Add(rv);
            return rv;
        }
        Node _parent;
        public Node Parent
        {
            get
            {
                return _parent;
            }
            set
            {
                if (Parent!=null|| value == null) 
                {
                    Parent.Children.Remove(this);
                }
                else
                {
                    value.Children.Add(this);
                }
                _parent = value;
            }
        }
        public string Name { get; set; }
        NodeCollection _children;
        public override string ToString()
        {
            var rv = new StringBuilder(Name);
            foreach (Node ch in Children)
            {
                SubNodeToString(ch, rv);
            }
            return rv.ToString();
        }

        public int Level
        {
            get
            {
                return Parent != null ? this.Parent.Level + 1 : 0;
            }
        }
        void SubNodeToString(Node n, StringBuilder sb)
        {
            sb.Append("\n" + repeat("\t", n.Level));
            sb.Append(n.Name);
            sb.Append(string.Format(" (Parent: {0})", n.Parent.Name));
            foreach (Node ch in n.Children)
            {
                SubNodeToString(ch, sb);
            }
        }
        string repeat(string s, int count)
        {
            var rv = new StringBuilder();
            for (int i = 0; i < count; i++) { rv.Append(s); };
            return rv.ToString();
        }
        public NodeCollection Children
        {
            get
            {
                return _children;
            }
        }
        public class NodeCollection : System.Collections.ObjectModel.Collection<Node>
        {
            internal NodeCollection(Node owner)
            {
                _owner = owner;
            }
            Node _owner;
            protected override void InsertItem(int index, Node item)
            {
                if (!this.Contains(item))
                {
                    base.InsertItem(index, item);
                    item._parent = _owner;
                }
            }
            protected override void RemoveItem(int index)
            {
                this[index]._parent = null;
                base.RemoveItem(index);
            }

        }
    }
}



Добавлено через 2 минуты и 18 секунд
Выводит следующее
Код

root
        child1 (Parent: root)
                child1_1 (Parent: child1)
                child1_2 (Parent: child1)
        child2 (Parent: root)
                child2_1 (Parent: child2)
                child2_2 (Parent: child2)

Удаляем узлы

root
        child1 (Parent: root)
                child1_1 (Parent: child1)
                child1_2 (Parent: child1)
        child2 (Parent: root)



--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
neutrino
Дата 17.8.2009, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Gothic soul
****


Профиль
Группа: Модератор
Сообщений: 3041
Регистрация: 25.3.2002
Где: Верхняя Галилея, Кармиэль

Репутация: 3
Всего: 62



diadiavova, да, конечно. Я просто провел параллель с кодом топикстартера. Конечно твоя модель с Method Factory лучше, удобней и безопасней. Я подумал, что ICollection дает много flexibility... Можно конечно сделать generic:

Код

TreeNode<ChildrenCollectionT> where ChildrenCollectionT : ICollection ...


Тогда есть и гибкость и безопасность.


--------------------
The truth comes from within ...

Покойся с миром, Vit 
PM MAIL WWW ICQ Skype GTalk   Вверх
diadiavova
Дата 17.8.2009, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



neutrino, ну там, вообще-то, главная фишка - сама коллекция, где отлавливается добавление/удаление элементов и идёт работа с парентом. Я сопсно об этом, остальное это просто, чтобы в примере сформировать дерево быстрее.

Добавлено через 5 минут и 33 секунды
То есть в примере я этого явно не показал, но если просто узел добавить в коллекцию Children, то свойство парент будет установлено автоматически(в коллекции). Вот я о чём smile 


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Rohoss
Дата 17.8.2009, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 2
Всего: 18



А зачем изобретать велосит, а не использовать скажем классы для работы с xml? Чем не дерево?


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
diadiavova
Дата 17.8.2009, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



Цитата(Rohoss @  17.8.2009,  20:19 Найти цитируемый пост)
А зачем изобретать велосит, а не использовать скажем классы для работы с xml? Чем не дерево? 

Ну я, скорее всего, так и сделал бы. Но кому-то, возможно, это не подходит.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
ReFLeXive
Дата 31.10.2009, 20:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 120
Регистрация: 30.3.2009
Где: г. Уфа

Репутация: нет
Всего: 1



Скажите плиз, а указанный выше способ подойдет для построения идеально сбалансированного дерева?
Помимо построения, мне необходимо вывести такое дерево графически. 
Подскажите плиз в каком направлении двигаться

PS. Решил не плодить новые темы с этой проблемой - воспользовался поиском и написал тут)))
PM MAIL   Вверх
diadiavova
Дата 31.10.2009, 21:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 31
Всего: 142



Вообще-то тут речь шла не о бинарных деревьях. В бинарном дереве у каждого узла есть только два подузла, а не целая коллекция и соответственно лучше для каждого подузла создать собственное свойство(например Left и Right). Что до графического вывода, то из стандартных инструментов есть только TreeView, а если не подходит, то или рисовать самому, или искать готовый контрол на стороне.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0963 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.