Tree structure +2 children - c#

I implemented a tree structure in c# where a node looks like the following
public class Node
{
public int ID{get;set;}
public string Name{get;set;}
public Node Parent {get;set;}
public IList<Node> Children{get;set;}
public IList<Object> Items{get;set;}
public IEnumerable<Ancestors> {get{return this.GetAncestors();}}
}
I want to improve my structure but i am not sure what is this kind of tree is called, its not a binary tree since the children count varies and can be more than 2, i use recursion for almost every operation from getting a node by Name,Id or reference to removing nodes, in my case when a node is removed i add both the Items and Children Properties to the Parent node.
I did it from scratch and i am sure someone did it better, so could you please help me figure the name of this tree structure so i can google it for improvements?

k-ary tree is probably the closest to what you're looking for. This typically refers to a tree where each node has at most k children (for some k, e.g. a binary tree is a 2-ary tree).
If you're looking for the case where the number of children per node is unbounded, I don't believe that has a specific name, it's just called a tree (although I imagine some resources might call that a k-ary tree as well).
An obvious place for improvement I see here is to use generics for your structure (you should replace IList<Object> with a generic data type, and rename Items to Data ... probably).
Without knowing what you want to do, I can't say whether IList<Object> is a good idea - an alternative might be to have a class with members with specific types instead, or IList<SomeOtherType>.
Having each node store a reference to its parent is not that typical, but if there's a need for it, it can be done.

There are a few places where these structures are also called n-ary trees . If you want examples , you can google for Tries and B-tree.
I think a trie comes closest to what you are trying to structure

Related

Modeling an XML hierarchy for traversal with MVVM

I have a good sized (4 MB) XML file that looks like this:
<A>
<B>
<C>
<D>
<D>
...
There are many C's and many B's. There is one A.
What I am trying to do is represent each level with a class that includes a GetChildren method which queries the XML file and returns a List<> of child objects. So calling ClassA.GetChildren() would return List<ClassB> and so on.
The second capability I want is for the user to be able to walk the hierarchy. So in the UI, I will display a list of the B objects. When the user clicks on a B, I want to drill in and re-populate the list with all of the C's under the selected B.
I am doing the MVVM pattern here, so I have a ViewModel where I would like to keep track of the current object. I guess I will also need to keep track of the parent objects too, so the user can use breadcrumbs to walk back up.
So I am looking for assistance in implementing this data model. I have tried a number of variations but can't quite cover all the bases. Currently I have this:
interface IMyData<T>
{
List<T> GetChildren();
}
And for each node A, B, C, and D, I have a class like so:
public class ClassB : IMyData<ClassC>
{
public List<ClassC> GetChildren()
{
...
}
}
One thing I am unable to do with this setup is store the current object in a single property, because of the way IMyData is defined with a generic. I feel like there must be an elegant way to do this but it's just not coming to me.

Extending the TreeView control for incremental filtering/searching

I'm trying to extend the winforms TreeView control to allow incremental filtering and searching similar to the Solution Explorer in VS2012/VS2013.
Ideally, I would like it to be capable of replacing the existing TreeView with minimal code change - as far as the consumer is concerned, the only difference would be a method void Filter(string). Because of this, I think it would make sense for the Nodes property to return the TreeNodeCollection with ALL nodes, even ones not showing because of an applied filter.
I have the code written to handle the filtering, and it actually works quite well except when I access base.Nodes, it returns my filtered nodes and not the full list.
The problem I have is, I'm unable to clone or create a new instance of TreeNodeCollection, because the constructor is marked as internal. So my ideal code would look something like this:
public class TreeViewEx : TreeView
{
// results in a compiler error:
private TreeNodeCollection _allNodes = new TreeNodeCollection();
public new TreeNodeCollection Nodes { get { return _allNodes; } }
public TreeNodeCollection FilteredNodes { get { return base.Nodes; } }
public void Filter(string searchString)
{
base.BeginUpdate();
base.Nodes.Clear();
foreach (TreeNode node in FilterInternal(_allNodes, searchString))
{
base.Nodes.Add(node);
}
base.EndUpdate();
}
}
So as you can see, I'm trying to decouple the nodes that are shown in the UI from the nodes that the consumer would access. Of course with TreeNodeCollection having an internal constructor only, I'm unable to create a new instance or clone it.
I considered these two options, but neither sound like good solutions:
Use reflection to instantiate the TreeNodeCollection object (due to the internal constructor) for the second list. This option seems like it would be more efficient than #2, but of course I'm creating an instance of an object I'm not supposed to.
Instantiate a second TreeView in memory and use the Nodes property from that to maintain my second list. This seems like it might be a lot of overhead.
I want the end result to still be a TreeNodeCollection so the TreeView can be used to replace our existing controls with minimal code and we do have several places using the Find method, which doesn't exist in List<TreeNode>.
Does anyone have any recommendations on how to handle this? What about performance/resource-wise with my two considerations?
Thank you
Update 1:
Per Pat's recommendation, I decided to take a step back and avoid messing with Nodes altogether. So now I've added a List<TreeNode> AllNodes property and have the Nodes just display the nodes that appear in the TreeView (the filtered list), so now it's a bit simpler.
My problem now is, how do I know when AllNodes has an item added to it so I can keep Nodes in sync? I've considered using a BindingList so I have the ListChanged event, but then I would need to have my TreeNode and node's children/grand-children/etc (AllNodes[0].Nodes) use a custom class that inherits from TreeNode and change the Nodes property, and TreeNode.Nodes isn't overridable. Is there another way? I could make a new property called NodeExs or something, but that seems very unintuitive and I could see another dev coming along later and pulling his hair out because the Nodes property is there but doesn't work.
With regard to your proposed solutions, #2 is out because a TreeNode cannot belong more than one control. And while it might be possible to create an instance of TreeNodeCollection via reflection, it won't be very useful because its designed to be coupled to a TreeView or another TreeNode. You won't be able to add/remove nodes from the collection.
Because of this, I think it would make sense for the Nodes property to
return the TreeNodeCollection with ALL nodes, even ones not showing
because of an applied filter.
I disagree, the TreeNodeCollection returned by the Nodes property is used by the framework and OS to render the control. You really don't want to hide this property or alter its functionality.
If a consumer needs to have access to _allNodes, create a List<TreeNode> AllNodes property or use a custom collection.
I've found out that the TreeNodeCollection should only be used to read the listed nodes. Instead, I've used List<TreeNode> to list nodes. In my project, I created a List<TreeNode> for each level on the TreeView. I filled the lists at the same time when I filled the TreeView, at the startup. In the end, I used AddRange() to make and combine a list of the all nodes. This way I had all the nodes listed and categorized.
It's easy and fast to create this kinds of lists. I also created a List<string> version of the all nodes list, which I set up as an AutoCompleteCustomSource for my TextBox. This way I was able to use TextBox with AutoComplete for searching the nodes.
I'd make different lists for the consumers and other categories. Then I'd only add the items to the TreeView which meet the given criteria. You can also use treeView.Nodes.Remove() to remove any nodes. You'd still have the actual node stored on the lists, and could add it back again later.
These are just some ideas.

Unit testing simple Tree structure manipulations

Given a very simple structure such as this:
public class TreeNode
{
public int ID { get; set; }
public List<TreeNode> Children { get; set; }
}
TreeNode may have other properties.
And when used in the following manner:
var tree = new List<TreeNode>(); //no root node
If I perform add/update/remove operations on the tree based on certain criteria. For example, removal of a node based on one or more of the other properties I mentioned above, I'd like to compare the tree graph before and after the changes and then via unit tests verify some of the follow:
Tree remains unchanged
Specified nodes are removed
Specified nodes are added
Specified nodes are updated
The 3 above whilst also verifying that the rest of the tree is unchanged.
Ideally, I'd throw an expection listing the nodes that were not found, not expected etc. However, at this stage I'd be happy with a true/false to my check.
Are there any known patterns/alogorithms existing projects that would help with this?
I am happy for pseudo-code or examples in other languages as long as they don't rely on features I can't replicate in .NET.
My tree is unlikely to get to more than 7 or 8 levels deep and no more than a hundred nodes in total as it will be test data so brute force looping is fine and performance isn't a consideration at this time.
I'm really looking for tips, tricks, advice, code on how to approach this.
TIA
When I did unit tests for tree structures, I simply built an ad-hoc tree of already known structure, execute operations on it and verified that the changes are exactly the ones I expected, a very simple but usable method, if you create good test cases.
Regardless my experience, you may think of some recursive comparison methods for tree nodes that may return a list of children nodes which are different. So the basic idea is to maintain two equal trees, perform operation on one of them, then check what was changed.
If you don't have any UI that shows the tree, I'd also recommend to make visualizations of a tree, using http://www.graphviz.org/ , you may generate pictures of your tree before and after some operation, so you will see how whole structure was changed(not usable for unit tests, but anyway).
And the last thing, I suggest to have a root node, it will simplify your recursive algorithms. If you don't have root, because of some requirments for UI or so, you may modify that part to simply ignore the root.
You can also have a function that get the string representation of the tree and simply compare 2 string representations instead of comparing 2 trees
I did that earlier this week
example function (swift)
public var description: String {
var s = "\(value)"
if !children.isEmpty {
s += " {" + children.map { "\($0.description)"}.joined(separator: ", ") + "}"
}
return s
}
You can test it like this
XCTAssert ( tree.description == "beverages {hot {tea {black, green, chai}, coffee, cocoa}, cold {soda {ginger ale, bitter lemon}, milk}}");

Querying using LINQ nested data structure and returning nested groups

Is there a way to do this but for a data structure that has an unknown level of nesting? Is addition, though I believe this was the case in the other question also, every level has more than one entry (assume this though it could have only one, or zero).
In addition, is there a good way to store such a data structure such that the parent of every object can be easily found? I was thinking of something like a jagged array, but that seems hard to generate at runtime, as I do not know how deep the nesting is. Something with a structure like a treeview would be ideal, but I don't want to implement a control if I will just be using it for data storage, and not for the visual part.
As a last resort, I was thinking of writing my own class to store the data, but don't want to do that if I don't have to.
Are you looking for an n-ary tree with parent references?
class Node
{
public Node Parent { get; }
public IEnumerable<Node> Children { get; }
}
IEnumerable<Node> Flatten(Node node)
{
yield return node;
foreach (var child in node.Children)
{
yield return Flatten(child);
}
}

Pattern to map Generic Data Structure to a Specific Data Structure

I have a hierarchical generic data structure. There is a root node and under that there can be many tree nodes, or just a single data node, and tree nodes can have more tree nodes. A basic tree structure.
All data in my system is persisted in this format. I do however want to have a strongly typed interface to some of the different types of data that these data structures represent (ie. turn a generic hierarchical tree into a strongly typed address record).
I was planning on using an adapter pattern where I pass in a node to the adapter and it then exposes properties by interrogating the tree. This would also allow me to validate the tree (ie. that is has specific elements and that they have valid data in them). It also allows for extensibility (ie. the tree itself would also be exposed if there were additional data that was added at a later date).
Do you think this is the most optimal approach to achieve this or is there a simpler way?
Note: this is in C# and .Net 4.0.
Thanks!
An Adapter is usually used to bridge between two incompatible interfaces. That doesn't seem to be your problem here. In fact, I don't really see any problem -- as object languages are by nature hierarchical, you should be able to use a mostly 1-to-1 mapping between a class and a tree node.
Perhaps by "Adapter" you just mean a class that wraps a Node or whatever particular Object type that describes your tree nodes, and I'd agree. There should be fairly obvious parent-child relationships that you can describe by having your node classes own or somehow return an array of child node/classes, and the attributes as getters/setters. Any needed validation could be done by the setters, or if need be during construction as a class inspects a given node and its child nodes. Something like the following:
public class NodeFu {
private Node node;
public NodeFu(Node node){
this.node = node;
// perhaps traverse and validate node data here
}
public String getNodeAttribute(String attrName){
// pardon the offense, Demeter, only for demonstration...
return node.getAttributes().getNamedItem(attrName).toString();
}
public void setNodeAttribute(String attrName, attrValue){
node.setAttributeValue(attrName, attrValue);
}
public ArrayList<NodeFu> getChildren(){
ArrayList<NodeFu> children = new ArrayList<NodeFu>();
for (Node childNode : node.getChildNodes()){
children.add(new NodeFu(childNode));
}
return children;
}
}
I'm assuming you have more business logic to add to this class that will manipulate the data on the Node itself, otherwise the Node class would suffice and you could just use it directly.

Categories