I have the class:
class Node
{
public string Name;
public string Address;
public int Id;
public List<Node> Children = new List<Node>;
public Node Parent;
}
To represent a node in a tree.
Now I will like to remove the duplicate nodes from a tree. Take for instance the tree:
Note: green Foo != purple Foo
What algorithm will enable me to remove the duplicates from the tree in order to end up with:
-------------------------------------------
In order to determine that the green Foo is not equal (!=) to purple Foo I guess I need to have another property that stores the height of the node or some other property that will enable me to enable me to compare nodes. This is the property I think I need (CompareId):
class Node
{
public string Name;
public string Address;
public int Id;
public List<Node> Children = new List<Node>();
public Node Parent;
public string CompareId // <----------------- Property I need to compare
{
get
{
var temp = this.Name + this.Address + this.Id;
if (this.Parent == null)
return temp;
else
return temp + this.Parent.CompareId;
}
}
}
If you wish to create the same tree I have here is the code:
Node root = new Node() { Name = "Root", Id = 12, Address = "0x0A1F12" };
Node tom1 = new Node() { Name = "Tom", Id = 15, Address = "0x0F1A17", Parent=root };
root.Children.Add(tom1);
Node tom2 = new Node() { Name = "Tom", Id = 15, Address = "0x0F1A17", Parent = root };
root.Children.Add(tom2);
Node foo = new Node() { Name = "Foo", Id = 99, Address = "0x4C0012", Parent=root };
root.Children.Add(foo);
Node foo1 = new Node() { Name = "Foo", Id = 99, Address = "0x4C0012", Parent = tom1 };
tom1.Children.Add(foo1);
Node foo2 = new Node() { Name = "Foo", Id = 99, Address = "0x4C0012", Parent = tom1 };
tom1.Children.Add(foo2);
Node foo3 = new Node() { Name = "Foo", Id = 99, Address = "0x4C0012", Parent = tom2};
tom2.Children.Add(foo3);
Node foo4 = new Node() { Name = "Foo", Id = 99, Address = "0x4C0012", Parent = tom2};
tom2.Children.Add(foo4);
Node joe1 = new Node() { Name = "Joe", Id = 99, Address = "0x605C2C", Parent = foo };
foo.Children.Add(joe1);
Node joe2 = new Node() { Name = "Joe", Id = 99, Address = "0x605C2C", Parent = foo };
foo.Children.Add(joe2);
Features of TreeSet is the primary concern it is widely used in remove duplicates in the data structure as follows: TreeSet implements the SortedSet interface. So, duplicate values are not allowed and will be leftovers. Objects in a TreeSet are stored in a sorted and ascending order.
To remove a duplicate person, go to the profile of the person you want to delete, then click 'view full profile' and select the 'Relations' tab. While hovering over someone in the relations tab you will see a 'broken link' icon which will allow you to remove them from that family or the entire tree.
In a Binary Search Tree (BST), all keys in left subtree of a key must be smaller and all keys in right subtree must be greater. So a Binary Search Tree by definition has distinct keys.
Please, check this out:
public class Node
{
public string Name;
public string Address;
public int Id;
public List<Node> Children;
public Node Parent;
public Node()
{
this.Children = new List<Node>();
}
public string CompareId
{
get
{
var temp = string.Concat(this.Name, this.Address, this.Id);
if (this.Parent == null)
return temp;
else
return string.Concat(temp, this.Parent.CompareId);
}
}
public override bool Equals(object OtherNode)
{
if (OtherNode is Node)
return this.CompareId.Equals(((Node)OtherNode).CompareId);
else
return false;
}
public static Node RemoveDuplicatesFromTree(Node RootNode)
{
if (RootNode.Children.Count > 0)
{
List<Node> OldChildrenList = new List<Node>();
OldChildrenList.AddRange(RootNode.Children);
foreach (Node CurrentChild in OldChildrenList)
{
if (RootNode.Children.Any<Node>(x => x.Equals(CurrentChild)))
{
List<Node> Duplicates = RootNode.Children.Where(x => x.Equals(CurrentChild)).ToList<Node>();
Duplicates.ForEach(x =>
{
CurrentChild.Children = CurrentChild.Children.Union<Node>(x.Children).ToList<Node>();
RootNode.Children.Remove(x);
});
RootNode.Children.Add(CurrentChild);
}
Node.RemoveDuplicatesFromTree(CurrentChild);
}
}
return RootNode;
}
}
It may be needless to say, still. Usage:
Node.RemoveDuplicatesFromTree(root);
private void RemoveDuplicatesFromTree(Node root)
{
List<Node> nodesToBeremoved = new List<Node>();
root.Children.ForEach(p =>
{
if (!nodesToBeremoved.Contains(p))
{
nodesToBeremoved.AddRange(root.Children.Where(q => q.Name == p.Name && q != p));
}
});
for (int i = 0; i < nodesToBeremoved.Count; i++)
{
root.Children.Remove(nodesToBeremoved[i]);
}
if (root.Children != null && root.Children.Count > 0)
{
root.Children.ForEach(t => this.RemoveDuplicatesFromTree(t));
}
}
Just pass the root to this recursive function; it will trim all duplicates in the same level. You do not need to create a compare Id.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With