I was looking for a tree or graph data structure in C# but I guess there isn\'t one provided. An Extensive Examination of Data Structures Using C# 2.0 explains a bit about w
The generally excellent C5 Generic Collection Library has several different tree-based data structures, including sets, bags and dictionaries. Source code is available if you want to study their implementation details. (I have used C5 collections in production code with good results, although I haven't used any of the tree structures specifically.)
Yet another tree structure:
public class TreeNode<T> : IEnumerable<TreeNode<T>>
{
public T Data { get; set; }
public TreeNode<T> Parent { get; set; }
public ICollection<TreeNode<T>> Children { get; set; }
public TreeNode(T data)
{
this.Data = data;
this.Children = new LinkedList<TreeNode<T>>();
}
public TreeNode<T> AddChild(T child)
{
TreeNode<T> childNode = new TreeNode<T>(child) { Parent = this };
this.Children.Add(childNode);
return childNode;
}
... // for iterator details see below link
}
Sample usage:
TreeNode<string> root = new TreeNode<string>("root");
{
TreeNode<string> node0 = root.AddChild("node0");
TreeNode<string> node1 = root.AddChild("node1");
TreeNode<string> node2 = root.AddChild("node2");
{
TreeNode<string> node20 = node2.AddChild(null);
TreeNode<string> node21 = node2.AddChild("node21");
{
TreeNode<string> node210 = node21.AddChild("node210");
TreeNode<string> node211 = node21.AddChild("node211");
}
}
TreeNode<string> node3 = root.AddChild("node3");
{
TreeNode<string> node30 = node3.AddChild("node30");
}
}
BONUS
See fully-fledged tree with:
https://github.com/gt4dev/yet-another-tree-structure
Because it isn't mentioned I would like you draw attention the now released .net code-base: specifically the code for a SortedSet
that implements a Red-Black-Tree:
https://github.com/Microsoft/referencesource/blob/master/System/compmod/system/collections/generic/sortedset.cs
This is, however, a balanced tree structure. So my answer is more a reference to what I believe is the only native tree-structure in the .net core library.
I have added complete solution and example using NTree class above, also added "AddChild" method...
public class NTree<T>
{
public T data;
public LinkedList<NTree<T>> children;
public NTree(T data)
{
this.data = data;
children = new LinkedList<NTree<T>>();
}
public void AddChild(T data)
{
var node = new NTree<T>(data) { Parent = this };
children.AddFirst(node);
}
public NTree<T> Parent { get; private set; }
public NTree<T> GetChild(int i)
{
foreach (NTree<T> n in children)
if (--i == 0)
return n;
return null;
}
public void Traverse(NTree<T> node, TreeVisitor<T> visitor, string t, ref NTree<T> r)
{
visitor(node.data, node, t, ref r);
foreach (NTree<T> kid in node.children)
Traverse(kid, visitor, t, ref r);
}
}
public static void DelegateMethod(KeyValuePair<string, string> data, NTree<KeyValuePair<string, string>> node, string t, ref NTree<KeyValuePair<string, string>> r)
{
string a = string.Empty;
if (node.data.Key == t)
{
r = node;
return;
}
}
using
NTree<KeyValuePair<string, string>> ret = null;
tree.Traverse(tree, DelegateMethod, node["categoryId"].InnerText, ref ret);
In case you need a rooted tree data structure implementation that uses less memory, you can write your Node class as follows (C++ implementation):
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
}
Most trees are formed by the data you are processing.
Say you have a
person
class that includes details of someone’sparents
, would you rather have the tree structure as part of your “domain class”, or use a separate tree class that contained links to your person objects? Think about a simple operation like getting all thegrandchildren
of aperson
, should this code be in theperson
class, or should the user of theperson
class have to know about a separate tree class?
Another example is a parse tree in a compiler…
What both of these examples show is that the concept of a tree is part of the domain of the data and using a separate general purpose tree at least doubles the number of objects that are created as well as making the API harder to program again.
What we want is a way to reuse the standard tree operations, without having to re-implement them for all trees, while at the same time, not having to use a standard tree class. Boost has tried to solve this type of problem for C++, but I yet to see any effect for .NET get adapted.