我在c#中寻找树或图数据结构,但我猜没有提供。使用c# 2.0的数据结构的广泛检查。是否有一个方便的库通常用于提供这个功能?也许可以通过策略模式来解决文章中提出的问题。
我觉得实现我自己的树有点傻,就像实现我自己的数组列表一样。
我只想要一个一般的树,它可以是不平衡的。想象一个目录树。C5看起来很漂亮,但它们的树结构似乎被实现为更适合搜索的平衡红黑树,而不是表示节点的层次结构。
我在c#中寻找树或图数据结构,但我猜没有提供。使用c# 2.0的数据结构的广泛检查。是否有一个方便的库通常用于提供这个功能?也许可以通过策略模式来解决文章中提出的问题。
我觉得实现我自己的树有点傻,就像实现我自己的数组列表一样。
我只想要一个一般的树,它可以是不平衡的。想象一个目录树。C5看起来很漂亮,但它们的树结构似乎被实现为更适合搜索的平衡红黑树,而不是表示节点的层次结构。
当前回答
这是我自己的想法:
class Program
{
static void Main(string[] args)
{
var tree = new Tree<string>()
.Begin("Fastfood")
.Begin("Pizza")
.Add("Margherita")
.Add("Marinara")
.End()
.Begin("Burger")
.Add("Cheese burger")
.Add("Chili burger")
.Add("Rice burger")
.End()
.End();
tree.Nodes.ForEach(p => PrintNode(p, 0));
Console.ReadKey();
}
static void PrintNode<T>(TreeNode<T> node, int level)
{
Console.WriteLine("{0}{1}", new string(' ', level * 3), node.Value);
level++;
node.Children.ForEach(p => PrintNode(p, level));
}
}
public class Tree<T>
{
private Stack<TreeNode<T>> m_Stack = new Stack<TreeNode<T>>();
public List<TreeNode<T>> Nodes { get; } = new List<TreeNode<T>>();
public Tree<T> Begin(T val)
{
if (m_Stack.Count == 0)
{
var node = new TreeNode<T>(val, null);
Nodes.Add(node);
m_Stack.Push(node);
}
else
{
var node = m_Stack.Peek().Add(val);
m_Stack.Push(node);
}
return this;
}
public Tree<T> Add(T val)
{
m_Stack.Peek().Add(val);
return this;
}
public Tree<T> End()
{
m_Stack.Pop();
return this;
}
}
public class TreeNode<T>
{
public T Value { get; }
public TreeNode<T> Parent { get; }
public List<TreeNode<T>> Children { get; }
public TreeNode(T val, TreeNode<T> parent)
{
Value = val;
Parent = parent;
Children = new List<TreeNode<T>>();
}
public TreeNode<T> Add(T val)
{
var node = new TreeNode<T>(val, this);
Children.Add(node);
return node;
}
}
输出:
Fastfood
Pizza
Margherita
Marinara
Burger
Cheese burger
Chili burger
Rice burger
其他回答
如果你需要一个使用较少内存的根树数据结构实现,你可以这样写你的Node类(c++实现):
class Node {
Node* parent;
int item; // depending on your needs
Node* firstChild; //pointer to left most child of node
Node* nextSibling; //pointer to the sibling to the right
}
也有可能在LINQ中使用XML:
在c#中创建XML树(LINQ to XML)
在使用树时,XML是最成熟和最灵活的解决方案,而LINQ为您提供了所需的所有工具。 您的树的配置也变得更加清晰和用户友好,因为您可以简单地使用XML文件进行初始化。
如果你需要处理对象,你可以使用XML序列化:
XML序列化
我不喜欢树的方法。它使事情变得过于复杂,包括搜索或下钻,甚至ui控件填充。
我建议使用dictionary <TChild, TParent>这种非常简单的方法。这也允许节点或级别之间没有连接。
我对解做了一些扩展。
使用递归泛型声明和派生子类,可以更好地专注于实际目标。
注意,它不同于非泛型实现,你不需要将'node'转换为'NodeWorker'。
以下是我的例子:
public class GenericTree<T> where T : GenericTree<T> // recursive constraint
{
// no specific data declaration
protected List<T> children;
public GenericTree()
{
this.children = new List<T>();
}
public virtual void AddChild(T newChild)
{
this.children.Add(newChild);
}
public void Traverse(Action<int, T> visitor)
{
this.traverse(0, visitor);
}
protected virtual void traverse(int depth, Action<int, T> visitor)
{
visitor(depth, (T)this);
foreach (T child in this.children)
child.traverse(depth + 1, visitor);
}
}
public class GenericTreeNext : GenericTree<GenericTreeNext> // concrete derivation
{
public string Name {get; set;} // user-data example
public GenericTreeNext(string name)
{
this.Name = name;
}
}
static void Main(string[] args)
{
GenericTreeNext tree = new GenericTreeNext("Main-Harry");
tree.AddChild(new GenericTreeNext("Main-Sub-Willy"));
GenericTreeNext inter = new GenericTreeNext("Main-Inter-Willy");
inter.AddChild(new GenericTreeNext("Inter-Sub-Tom"));
inter.AddChild(new GenericTreeNext("Inter-Sub-Magda"));
tree.AddChild(inter);
tree.AddChild(new GenericTreeNext("Main-Sub-Chantal"));
tree.Traverse(NodeWorker);
}
static void NodeWorker(int depth, GenericTreeNext node)
{ // a little one-line string-concatenation (n-times)
Console.WriteLine("{0}{1}: {2}", String.Join(" ", new string[depth + 1]), depth, node.Name);
}
大多数树是由您正在处理的数据形成的。
假设您有一个person类,其中包含某人的细节 父母们,你们愿意让树形结构成为你们的一部分吗 “域类”,或者使用包含链接的单独树类 你的人反对吗?考虑一个简单的操作,比如获取全部 一个人的孙子,应该是这个人的密码 类,或者person类的用户必须知道 单独的树类?
另一个例子是编译器中的解析树…
这两个例子都表明,树的概念是数据域的一部分,使用单独的通用树至少会使创建的对象数量增加一倍,同时也会使API更难再次编程。
我们想要一种重用标准树操作的方法,而不必为所有树重新实现它们,同时又不必使用标准树类。Boost已经尝试为c++解决这类问题,但是我还没有看到任何对. net进行适应的效果。