How to find the next element in the tree - c#

I have a tree like below:
/* Tree
* 5
* / \
* 3 1
* / \ / \
* 2 4 6 7
*/
I am creating this tree using a class called Node as below:
var root = new Node(
5,
new Node(
3,
new Node(2),
new Node(4)),
new Node(
1,
new Node(6),
new Node(7)));
I wanted as a result to print out the ordered tree: 1 2 3 4 5 6 7.
I am able to find the next larger element referring to this example https://www.geeksforgeeks.org/next-larger-element-n-ary-tree/ , but I can't find out how to print the all nodes in order.
Edited:
public static class Program
{
static void Main(string[] args)
{
var root = new Node(
5,
new Node(
3,
new Node(2),
new Node(4)),
new Node(
1,
new Node(6),
new Node(7)));
var n = root;
while (n != null)
{
Console.WriteLine(n.Data);
n = n.NextNode();
}
}
public static Node NextNode(this Node node)
{
var newNode = NextLargerElement(node, node.Data);
return newNode;
}
public static Node res;
public static Node NextLargerElementUtil(Node root, int x)
{
if (root == null)
return null;
if (root.Data > x)
if ((res == null || (res).Data > root.Data))
res = root;
foreach (var children in root.Children)
{
NextLargerElementUtil(children, x);
}
return res;
}
static Node NextLargerElement(Node root, int x)
{
res = null;
NextLargerElementUtil(root, x);
return res;
}
}
And the Node class:
public class Node
{
private List<Node> _children;
public Node(int data, params Node[] nodes)
{
Data = data;
AddRange(nodes);
}
public Node Parent { get; set; }
public IEnumerable<Node> Children
{
get
{
return _children != null
? _children
: Enumerable.Empty<Node>();
}
}
public int Data { get; private set; }
public void Add(Node node)
{
//Debug.Assert(node.Parent == null);
if (_children == null)
{
_children = new List<Node>();
}
_children.Add(node);
node.Parent = this;
}
public void AddRange(IEnumerable<Node> nodes)
{
foreach (var node in nodes)
{
Add(node);
}
}
public override string ToString()
{
return Data.ToString();
}
}

You need a recursive / iterator function to iterate over all the branches and get all the nodes:
public IEnumerable<Node> GetAllNodes(Node parent)
{
IEnumerable<Node> GetAllNodes(IEnumerable<Node> children)
{
foreach(var child in children)
{
yield return child;
foreach(var c in GetAllNodes(child.Children))
yield return c;
}
}
yield return parent;
foreach(var child in GetAllNodes(parent.Children))
yield return child;
}
If you have a tree like:
var root = new Node(5,
new Node(3, new Node(11), new Node(12),
new Node(2),
new Node(4), new Node(13)),
new Node(1, new Node(14), new Node(15),
new Node(6, new Node(16), new Node(17)),
new Node(7, new Node(8), new Node(9))), new Node(10));
Call the function, pass the root node, and OrderBy the Data property:
var q = GetAllNodes(root).OrderBy(x => x.Data).Select(x => x.Data);
Console.WriteLine(string.Join(", ", q));
The output is:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17
Preferably, make it an extension method for the Node type.
static class Extensions
{
public static IEnumerable<Node> GetAllNodes(this Node parent)
{
IEnumerable<Node> GetAllNodes(IEnumerable<Node> children)
{
foreach (var child in children)
{
yield return child;
foreach (var c in GetAllNodes(child.Children))
yield return c;
}
}
yield return parent;
foreach (var child in GetAllNodes(parent.Children))
yield return child;
}
}
So you can call it as follows:
var q = root.GetAllNodes().OrderBy(x => x.Data).Select(x => x.Data);
Console.WriteLine(string.Join(", ", q));

Related

After adding value in Dictionary (map) when I print the Dictionary its show all value same (value.data)

** after print Dictionary all values are same. Why?? Where is the problem??**
** after print Dictionary all values are same. Why?? Where is the problem??**
** after print Dictionary all values are same. Why?? Where is the problem??**
** after print Dictionary all values are same. Why?? Where is the problem??**
In Dictionary I added Key as int and value as an object(Node)
In Dictionary I added Key as int and value as an object(Node)
In Dictionary I added Key as int and value as an object(Node)
In Dictionary I added Key as int and value as an object(Node)
using System;
using System.Collections.Generic;
using System.Linq;
namespace Tree1
{
public class Node
{
public int data;
public Node left, right;
}
public class NewNode
{
Node node = new Node();
public Node createNode(int key)
{
node.data = key;
//Console.WriteLine(key);
node.left = node.right = null;
return node;
}
}
public class Print
{
Node node = new Node();
public void inorder(Node root)
{
if (root == null)
return;
inorder(node.left);
//Console.WriteLine(node.data+" ");
inorder(node.right);
}
}
public class BinaryTree
{
Node root = new Node();
NewNode newNode = new NewNode();
public Node createTree(int[] parent, int n)
{
Dictionary<int, Node> map = new Dictionary<int, Node>();
for (int i = 0; i<n; i++)
{
map.Add(i,newNode.createNode(i));
//Console.WriteLine(map.Keys + " " + map[i].data);
}
foreach (var pair in map)
{
int key = pair.Key;
Node value = pair.Value;
Console.WriteLine(key + "/" + value.data);
}
root = null;
for(int i = 0; i<n; i++)
{
if(parent[i] == -1)
{
root = map[i];
}
else
{
Node ptr = map[parent[i]];
//Console.WriteLine(parent[i]);
//Console.WriteLine(ptr.data);
if (ptr.left != null)
{
ptr.right = map[i];
}
else
{
ptr.left = map[i];
}
}
}
return root;
}
}
class Program
{
static void Main(string[] args)
{
int[] parent = new int[] { -1, 0, 0, 1, 2, 2, 4, 4};
BinaryTree binaryTree = new BinaryTree();
Node root = new Node();
root = binaryTree.createTree(parent, parent.Length);
Print print = new Print();
print.inorder(root);
Console.ReadLine();
}
}
}
[enter image description here][1]
You need a constructor in your node class.
public class Node
{
public int data;
public Node left, right;
public Node(int data){
this.data = data;
}
}
Then when you create a new Node, you can pass the value you want to be set as data.
var newNode = new Node(value);

How to find the next node in a tree?

The problem goes like this:
We have a tree that is built using the class Node where an instance of the class represents a node in the tree. For simplicity, the node has a single data field of type int.
Your task is to write the extension method NodeExtensions.Next() to find the next element in the tree. You can write as many helper methods as you want, but don't change the signature of the extension method NodeExtensions.Next().
I have this Node class:
public class Node
{
private List<Node> _children;
public Node(int data, params Node[] nodes)
{
Data = data;
AddRange(nodes);
}
public Node Parent { get; set; }
public IEnumerable<Node> Children
{
get
{
return _children != null
? _children
: Enumerable.Empty<Node>();
}
}
public int Data { get; private set; }
public void Add(Node node)
{
Debug.Assert(node.Parent == null);
if (_children == null)
{
_children = new List<Node>();
}
_children.Add(node);
node.Parent = this;
}
public void AddRange(IEnumerable<Node> nodes)
{
foreach (var node in nodes)
{
Add(node);
}
}
public override string ToString()
{
return Data.ToString();
}
}
The solution should be a extension method such as this
public static Node Next(this Node node)
{
}
The code I tried:
public static Node Next(this Node node)
{
var newNode = NextLargerElement(node, node.Data);
return newNode;
}
public static Node res;
public static Node NextLargerElementUtil(Node root, int x)
{
if (root == null)
return null;
if (root.Data > x)
if ((res == null || (res).Data > root.Data))
res = root;
foreach (var children in root.Children)
{
NextLargerElementUtil(children, x);
}
return res;
}
static Node NextLargerElement(Node root, int x)
{
res = null;
NextLargerElementUtil(root, x);
return res;
}
Here is a testing case:
[Test]
public void Test()
{
// Test tree:
//
// 1
// +-2
// +-3
// +-4
// +-5
// +-6
// +-7
//
var root = new Node(
1,
new Node(
2,
new Node(3),
new Node(4)),
new Node(
5,
new Node(6),
new Node(7)));
// Expected output:
//
// 1
// 2
// 3
// 4
// 5
// 6
// 7
//
var n = root;
while (n != null)
{
Console.WriteLine(n.Data);
n = n.Next();
}
// Test
//
n = root;
Assert.AreEqual(1, n.Data);
n = n.Next();
Assert.AreEqual(2, n.Data);
n = n.Next();
Assert.AreEqual(3, n.Data);
n = n.Next();
Assert.AreEqual(4, n.Data);
n = n.Next();
Assert.AreEqual(5, n.Data);
n = n.Next();
Assert.AreEqual(6, n.Data);
n = n.Next();
Assert.AreEqual(7, n.Data);
n = n.Next();
Assert.IsNull(n);
}
You can use Equals to backtrack your current node position in the tree and return it's parent's next child, if any, if there is not one then you need to backtrack the current node parent position and so on:
public static Node Next(this Node node)
{
if(node.Children != null && node.Children.Any())
{
return node.Children.First();
}
// "backtracking", also can be done recursively
var parent = node.Parent;
while(parent != null)
{
var returnNext = false; // return next element in Children if current is node
foreach (var element in parent.Children)
{
if(returnNext)
{
return element;
}
if(element == node)
{
returnNext = true;
node = parent; // to find parent's position if there is no next child
}
}
parent = parent.Parent;
}
return null;
}

How to delete nodes in my binary search tree

I have created a binary search tree, and am stuck on how to delete a node from my tree. My code currently looks like this:
public class Node
{
public int value;
public int id;
public Node left, right;
public Node(int identifier, int v)
{
id = identifier;
value = v;
left = right = null;
}
}
public class BinaryTree
{
public static Node head;
public virtual Node insert(Node node,int id, int value)
{
if (node == null)
{
return (new Node(id, value));
}
else
{
if (value <= node.value)
{
node.left = insert(node.left, id, value);
}
else
{
node.right = insert(node.right, id, value);
}
return node;
}
}
public virtual int maxvalue(Node node)
{
Node current = node;
while (current.right != null)
{
current = current.right;
}
return (current.id);
}
public static void Main(string[] args)
{
BinaryTree bt = new BinaryTree();
Node root = null;
root = bt.insert(root, 4, 5);
root = bt.insert(root, 9, 6);
root = bt.insert(root, 16, 3);
Console.WriteLine(bt.maxvalue(root));
root = bt.insert(root, 12, 8);
Console.WriteLine(bt.maxvalue(root));
Console.WriteLine(bt.maxvalue(root));
}
}
What I want to do is, every time I print out the id of the node with the highest value, I then want delete that node from my BST. However, I do not know how to implement this function, so if anyone knows how, I would appreciate it.

recursive function in collection

I am using c# and List collection and loaded the values. Once it is done I am trying to read them recursively but some how I am not able to achieve this.
the following is my main code.
private static void Main(string[] args)
{
var node = new Node
{
Name = "N1",
Nodes =
new List<Node>
{
new Node { Name = "N1a" },
new Node { Name = "N1b", Nodes = new List<Node> { new Node { Name = "N1B1" } } },
new Node
{
Name = "N1c",
Nodes =
new List<Node> { new Node { Name = "N1C1", Nodes = new List<Node> {new Node{Name = "N1C1A"} } } }
}
}
};
GetNodes( node );
Console.ReadLine();
}
public class Node
{
public string Name { get; set; }
public IList<Node> Nodes { get; set; }
}
and the function call is following
public static IEnumerable<Node> GetNodes(Node node)
{
if (node == null)
{
return null;
}
Console.WriteLine(node.Name);
foreach (var n in node.Nodes)
{
return GetNodes(n);
}
return null;
}
}
Could any one please help me to fix the recursive function?
If you just want to print the names of all the nodes,
public static void GetNodes(Node node)
{
if (node == null)
{
return;
}
Console.WriteLine(node.Name);
foreach (var n in node.Nodes)
{
GetNodes(n);
}
}
If you want to flatten the tree,
public static IEnumerable<Node> GetNodes(Node node)
{
if (node == null)
{
yield break;
}
yield return node;
foreach (var n in node.Nodes)
{
foreach(var innerN in GetNodes(n))
{
yield return innerN;
}
}
}
public static IEnumerable<Node> GetNodes(Node node)
{
if (node == null) return null;
var nodes = new List<Node>();
nodes.Add(node);
Console.WriteLine(node.Name);
if (node.Nodes != null)
{
foreach (var n in node.Nodes)
{
nodes.AddRange(GetNodes(n));
}
}
return nodes;
}}
Your method only every returns null, or calls itself and then either returns null, or calls itself..... so at the end of the day it returns null or doesn't terminate. If you want to seralize the values you can write them into a list at the same point in the code as you write them to the console.
public static void GetNodes(Node node, List<Node> output)
{
if (node == null)
return;
output.Add(node);
Console.WriteLine(node.Name);
foreach (var n in node.Nodes)
{
GetNodes(n, output);
}
}
You return from your method inside a loop immediately, on teh first iteration. No other iterations is performed.

Remove duplicates from tree

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);
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.
static void RemoveDuplicates(ref Node root)
{
Dictionary<string, Node> nonDuplicates = new Dictionary<string, Node>();
Action<Node> traverseTree = null;
traverseTree = (x) =>
{
var compareId = x.CompareId;
if (nonDuplicates.ContainsKey(compareId)) // if there is a duplicate
{
x.Parent.Children.Remove(x); // remove node
}
else
{
nonDuplicates.Add(compareId, x);
}
// cannot use foreach loop because removing a node will result in exception
// keep traversing the tree
for (var i = x.Children.Count - 1; i >= 0; i--)
traverseTree(x.Children[i]);
};
traverseTree(root);
}

Categories