How to clone a whole tree without affecting the original one? - c#

i use the solution in this link not work
Deep cloning objects
the following code, can not copy to a new tree, mutate will affect the original tree root(root)
foreach (Bag b in bag_list)
{
if (b.cards.Count() == 2)
{
Node original_root = new Node();
original_root = (Node)root.Clone(); // copy to a new tree
target_list = choose_valid_target(target_list, b.cards, b.cards.Count() - 1);
foreach (Target t in target_list)
{
Console.WriteLine("op:" + t.op + ", label:" + t.label);
Node mutated_root = mutate(original_root, target_list);
result = "";
result = inorder(mutated_root, result); // get inorder
Console.WriteLine(result.Substring(1, result.Length - 2)); //print
}
}
}
public class Node : System.Object, ICloneable
{
public int priority;
/*
7 alphabet
6 (,)
5 *,/,%
4 +,-
3 <,<=,>,>=
2 &&,||
1 =
*/
public string Data;
public Node Left;
public Node Right;
public string Label;
public object Clone()
{
//return this as object;
return this.MemberwiseClone();
//return new Node() as object;
}
}
public Node mutate(Node root, List<Target> targets) // mutate
{
if (root != null)
{
if (!IsLeaf(root.Left.Data))
mutate(root.Left, targets);
foreach (Target target in targets)
{
if (root.Label == target.label)
{
root.Data = target.op;
}
}
if (!IsLeaf(root.Right.Data))
mutate(root.Right, targets);
}
return root;
}

Clone all nodes recursively:
public object Clone()
{
Node clone = (Node)MemberwiseClone();
if (Left != null)
clone.Left = (Node)Left.Clone();
if (Right != null)
clone.Right = (Node)Right.Clone();
return clone;
}

Related

How can i implement a pop method for a generic stack without traversing the list

I have a generic stack that I will use in a console application. I need the stack to behave like a .Net stack but with extra functionality. Below is part of the code for the stack
class DynamicGenericStack<T>
{
private class Node
{
public T element { get; private set; }
public Node Next { get; set; }
public Node(T element, Node prevNode)
{
this.element = element;
Next = null;
Previous = null;
if (prevNode != null) //if this is not the first node
prevNode.Next = this;
}
}
private Node head, tail;
public int Count { get; private set; } //Count
public DynamicStack()
{
this.head = null;
this.tail = null;
this.Count = 0;
}
public void Push(T item)
{
if (this.head == null)
this.head = this.tail = new Node(item, null);
else
tail = new Node(item, tail);
Count++;
} Push
public T Peek()
{
return tail.element;
} Peek
public T Pop()
{
if (Count > 0)
{
T item = tail.element;
Node prev = null, current = head;
while (current != tail)
{
prev = current;
current = current.Next;
}
tail = prev;
Count--;
return item;
}
return default(T);
}
}
How can I implement the pop method above to remove the tail node without having to traverse the entire list as I did in the above code using the while loop? Is there any way in which track the tail node and remove it directly?
A single linked list is good enough for a stack, and only a head reference is needed.
To push onto the stack:
create new_node
new_node.next = head;
head = new_node;
count++;
To pop from the stack:
if(count == 0)
return null;
tmp_node = head;
head = head.next;
count--;
return tmp_node.element;
In a stack you are not really interested in the bottom. You have three main methods:
push: adds a new item over the top
pop: removes the top
top: reads the top
Change 1: next -> prev
You will need to always track what the top is and therefore you will need to know what are the previous elements.
public Node Prev { get; set; }
Change 2: Apply the same idea for Node constructor
public Node(T element, Node prevNode)
{
this.element = element;
Next = null;
Previous = null;
if (prevNode != null) //if this is not the first node
prevNode.Prev = this;
}
Change 3: Apply this logic at Pop
public T Pop()
{
T element = default(T);
if (Count > 0)
{
element = tail.element;
if (tail.Prev != null) {
tail = tail.Prev;
} else {
head = tail = null;
}
}
return element;
}

Printing Tree and skipping certain values

here i have the following code and input that prints a tree structure. My question is how can i make it so that the nodes and leafs that have the value "Unavailable" are skipped from being printed.
namespace Tree{public class TreeNode<T>
{
private T value;
private bool hasParent;
private List<TreeNode<T>> children;
public TreeNode(T value)
{
if (value == null)
{
throw new ArgumentNullException("Cannot insert null value");
}
this.value = value;
this.children = new List<TreeNode<T>>();
}
public T Value
{
get
{
return this.value;
}
set
{
this.value = value;
}
}
public int ChildrenCount
{
get
{
return this.children.Count;
}
}
public void AddChild(TreeNode<T> child)
{
if (child == null)
{
throw new ArgumentNullException("Cannot insert null value");
}
if (child.hasParent)
{
throw new ArgumentException("The node already has a parent");
}
child.hasParent = true;
this.children.Add(child);
}
public TreeNode<T> GetChild(int index)
{
return this.children[index];
}
}
public class Tree<T>
{
private TreeNode<T> root;
public Tree(T value)
{
if (value == null)
{
throw new ArgumentNullException("Cannot insert null value");
}
this.root = new TreeNode<T>(value);
}
public Tree(T value, params Tree<T>[] children) : this(value)
{
foreach (Tree<T> child in children)
{
this.root.AddChild(child.root);
}
}
public TreeNode<T> Root
{
get
{
return this.root;
}
}
private void PrintDFS(TreeNode<T> root, string spaces)
{
if (this.root == null)
{
return;
}
Console.WriteLine(spaces + root.Value);
TreeNode<T> child = null;
for (int i = 0; i < root.ChildrenCount; i++)
{
child = root.GetChild(i);
PrintDFS(child, spaces + " ");
}
}
public void TraverseDFS()
{
this.PrintDFS(this.root, string.Empty);
}
}
public static class TreeExample
{
static void Main()
{
Tree<string> tree =
new Tree<string>("John",
new Tree<string>("Jasmine",
new Tree<string>("Jay"),
new Tree<string>("Unavailable")),
new Tree<string>("Unavailable",
new Tree<string>("Jack"),
new Tree<string>("Jeremy")),
new Tree<string>("Johanna")
);
tree.TraverseDFS();
}
}}
right now it prints :(John, (Jasmine, (Jay), (Unavailable)), (Unavailable, (Jack, (Jeremy))), (Johanna))
I need it to print :(John, (Jasmine, (Jay)), (Johanna))
So basically skip every leaf with the value "Unavailable" and every node with the value "Unavailable" and all children from that node
Thanks !
This should work:
private void PrintDFS(TreeNode<T> root, string spaces)
{
if (this.root == null
|| "Unavailable" == root.Value.ToString())
{
return;
}
...
The accepted answer is a literally correct answer to the question, but it bakes in logic about what to do with the tree into the tree itself. A tree is a kind of collection or data structure, and you don't often see a List or Dictionary that is able to print itself. Instead the collection provides the right methods to get or change its contents so that you can do what you want.
In your case, you could do something like the following:
public enum TreeVisitorResult {
SkipNode,
Continue
}
// the following two methods inside Tree<T>:
public void VisitNodes(Func<TreeNode<T>, int, TreeVisitorResult> visitor) {
VisitNodes(0, this.root, visitor);
}
private void VisitNodes(int depth, TreeNode<T> node,
Func<TreeNode<T>, int, TreeVisitorResult> visitor) {
if (node == null) {
return;
}
var shouldSkip = visitor(node, depth);
if (shouldSkip == TreeVisitorResult.SkipNode) {
return;
}
TreeNode<T> child = null;
for (int i = 0; i < node.ChildrenCount; i++) {
child = node.GetChild(i);
VisitNodes(depth + 1, child, visitor);
}
}
If you had this method, you could write the Print method outside of the Tree classes, as:
tree.VisitNodes((treeNode, depth) => { // <- this lambda will be called for every node
if (treeNode.Value == "Unavailable") { // <- no need to ToString or cast here, since
// we know that T is string here
return TreeVisitorResult.SkipNode;
} else {
var spaces = new string(' ', depth * 3);
Console.WriteLine(spaces + treeNode.Value);
}
});

Why do we need Parent Node in Binary Search Tree - C#

I have only started learning Data Structures so please bear my stupidity, I am trying to develop my own version of BST, I can't get why there is a need of a parent Node? Shouldn't this work just fine.
class BST
{
private Node root;
public BST()
{
root = null;
}
public void insert(int value)
{
Node temp = new Node();
temp.value = value;
if (root == null)
{
root = temp;
return;
}
Node current = root;
while (current != null)
{
if (value <= current.value)
{
current = current.lc;
}
else
{
current = current.rc;
}
}
current = temp;
}
}
class Node
{
public Node lc;
public int value;
public Node rc;
}
There is definitely something that I am missing and I can't grasp or get what it is, when current is null, we are already onto where we need to insert the node, why then do we need a parent node.
This may work
class BST
{
private Node root = null;
public void insert(int value)
{
Node temp = new Node { value = value };
if (root == null)
{
root = temp;
return;
}
var current = root;
while (current != null)
{
if (value <= current.value)
{
if (current.lc == null)
{
current.lc = temp;
break;
}
current = current.lc;
}
else
{
if (current.rc == null)
{
current.rc = temp;
break;
}
current = current.rc;
}
}
}
}
class Node
{
public Node lc;
public int value;
public Node rc;
}
You are mixing variables with references to fields/variables. The current variable holds the value of the lc or rc field (the copy of the field). Setting the variable does not set the corresponding field, just assigns another value to the variable.
Hence the line
current = temp;
does not insert the node in the BST.
What you are trying to do is possible with C#7.0 introduced ref locals and returns and C#7.3 introduced improvements which allow to reassign ref local variables.
The ref local variables are exactly what is your intention - they contain the location (reference, address) of some other field / variable. So the following works (requires C#7.3!):
public void insert(int value)
{
ref Node nodeRef = ref root;
while (nodeRef != null)
{
if (value <= nodeRef.value)
nodeRef = ref nodeRef.lc;
else
nodeRef = ref nodeRef.rc;
}
nodeRef = new Node { value = value };
}
Note the usage of ref keyword. You use nodeRef = ref … to assign a reference (address) of a variable (in this case either root or some node lc or rc field), and nodeRef = … to assign a value to the variable pointed by the nodeRef.
You are setting "null" to some instance.
In your while loop current eventually becomes null, and you are missing the connection between nodes.
To fix this issue you should keep the last node of your tree.
You can try the below :
class BST
{
private Node root;
public BST()
{
root = null;
}
public void insert(int value)
{
root = insert(root, value);
}
private Node insert(Node node, int value) {
// if the given node is null it should be new node
if (node == null) {
node = new Node();
node.value = value;
return node;
}
if (value < node.value)
// if our value lower then current value then we will insert left node recursively
node.lc = insert(node.lc, value);
else if (value > node.value)
// if our value higher then current value then we will insert right node recursively
node.rc = insert(node.rc, value);
return node;
}
public void print() {
print(root);
}
private void print(Node node) {
if (node != null) {
print(node.lc);
Console.WriteLine(node.value);
print(node.rc);
}
return;
}
}
public static void main(String[] args) {
BST bst = new BST();
bst.insert(5);
bst.insert(25);
bst.insert(15);
bst.insert(4);
bst.print();
}
The output is :
4
5
15
25

Search tree, simplest method for traversing c#

I need to be able to search a tree with arbitrary many children.
It could look like this.
P
/ | \
C C C layer 1
/ | \
C C C layer 2
|
C layer 3
/ | \
C C C layer 4
With arbitrary many children in each C.
Is it convinient to have a double linked list for each start node in layer 1? (In layer 1 the non expanding nodes might also ofcourse expand).
I need to evaluate and work with every sub-tree.
Whats the simplest method?
Or maybe some kind of depth first search/breadth first search is better?
The tree is constructed on the fly.
thanks
The easiest way to do this is using recursion.
Let's assume that your tree stores items of type T, and that type implements IEquatable<T>.
Firstly, let's write a very basic tree class:
public sealed class Node<T>
{
public Node(T value) { Value = value; }
public T Value { get; }
public IEnumerable<Node<T>> Children => _children;
public void Add(Node<T> child)
{
_children.Add(child);
}
readonly List<Node<T>> _children = new List<Node<T>>();
}
Now we can write a method to search that tree using recursion very simply.
This will return the first node containing the specified value if it was found, or null if no such node was found.
public static Node<T> Find<T>(Node<T> root, T target) where T: IEquatable<T>
{
if (root.Value != null && root.Value.Equals(target))
return root;
foreach (var child in root.Children)
{
var found = Find(child, target);
if (found != null)
return found;
}
return null;
}
It's easy to adapt this to return ALL nodes that match the target:
public static IEnumerable<Node<T>> FindAll<T>(Node<T> root, T target) where T : IEquatable<T>
{
if (root.Value != null && root.Value.Equals(target))
yield return root;
foreach (var child in root.Children)
{
var found = FindAll(child, target);
foreach (var item in found)
yield return item;
}
}
For demo purposes, here's a compilable console application. It includes a makeTree() method which I'm using to make a tree of depth 4 where each node has 5 children.
Then it uses Find<T>(Node<T> root, T target) to recursively search the tree to find the specified target values. One will succeed, the other will fail:
using System;
using System.Collections.Generic;
namespace Demo
{
public sealed class Node<T>
{
public Node(T value) { Value = value; }
public T Value { get; }
public IEnumerable<Node<T>> Children => _children;
public void Add(Node<T> child)
{
_children.Add(child);
}
readonly List<Node<T>> _children = new List<Node<T>>();
}
class Program
{
static void Main()
{
var root = makeTree(1, 1, 4, 5);
lookFor(root, "3.4");
lookFor(root, "6.3");
}
static void lookFor<T>(Node<T> root, T target) where T: IEquatable<T>
{
var found = Find(root, target);
Console.WriteLine(found != null ? $"Found {target}" : $"Did not find {target}");
}
public static Node<T> Find<T>(Node<T> root, T target) where T: IEquatable<T>
{
if (root.Value != null && root.Value.Equals(target))
return root;
foreach (var child in root.Children)
{
var found = Find(child, target);
if (found != null)
return found;
}
return null;
}
static Node<string> makeTree(int id1, int id2, int depth, int nChildren)
{
var root = new Node<string>($"{id1}.{id2}");
if (depth == 0)
return root;
for (int i = 0; i < nChildren; ++i)
root.Add(makeTree(id1+1, i+1, depth-1, nChildren));
return root;
}
}
}

Build a simple, high performance Tree Data Structure in c#

I need to create a product catalog, in tree type.
every tree node presents by a ID(string), the functions on the tree data only 2:
getChild(string ID), give a ID, get children (no need include childrens'
children), if ID is null, get all root nodes
getParent(string ID), return parent ID if have, or null if is root
Since once the tree decided, will not change, so I think put all code in static will be best.
So I start to try use Dictionary
"id": {parent:ID, child:[id2, id3, id4....]}
Since theres about 1000+ catalog, I found I quickly mess myself up, lots of mistake in the static data, and make final result on usable. Also, now I only wrote dozens and the code is looking like mess.
Please advice a way create this simple catalog tree with high performance. Thanks
Just make a class out of it.
UPDATED:
class TreeNode : IEnumerable<TreeNode>
{
private readonly Dictionary<string, TreeNode> _children =
new Dictionary<string, TreeNode>();
public readonly string ID;
public TreeNode Parent { get; private set; }
public TreeNode(string id)
{
this.ID = id;
}
public TreeNode GetChild(string id)
{
return this._children[id];
}
public void Add(TreeNode item)
{
if (item.Parent != null)
{
item.Parent._children.Remove(item.ID);
}
item.Parent = this;
this._children.Add(item.ID, item);
}
public IEnumerator<TreeNode> GetEnumerator()
{
return this._children.Values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public int Count
{
get { return this._children.Count; }
}
}
Usage will be fairly simple to statically define:
var tree = new TreeNode("Root")
{
new TreeNode("Category 1")
{
new TreeNode("Item 1"),
new TreeNode("Item 2"),
new TreeNode("Item 3"),
},
new TreeNode("Category 2")
{
new TreeNode("Item 1"),
new TreeNode("Item 2"),
new TreeNode("Item 3"),
new TreeNode("Item 4"),
}
};
Edit
Some more functionality for even easier creation...
public static TreeNode BuildTree(string tree)
{
var lines = tree.Split(new[] { Environment.NewLine },
StringSplitOptions.RemoveEmptyEntries);
var result = new TreeNode("TreeRoot");
var list = new List<TreeNode> { result };
foreach (var line in lines)
{
var trimmedLine = line.Trim();
var indent = line.Length - trimmedLine.Length;
var child = new TreeNode(trimmedLine);
list[indent].Add(child);
if (indent + 1 < list.Count)
{
list[indent + 1] = child;
}
else
{
list.Add(child);
}
}
return result;
}
public static string BuildString(TreeNode tree)
{
var sb = new StringBuilder();
BuildString(sb, tree, 0);
return sb.ToString();
}
private static void BuildString(StringBuilder sb, TreeNode node, int depth)
{
sb.AppendLine(node.ID.PadLeft(node.ID.Length + depth));
foreach (var child in node)
{
BuildString(sb, child, depth + 1);
}
}
Usage:
var tree = TreeNode.BuildTree(#"
Cat1
Sub1
Item1
Item2
Item3
Sub2
Item1
Item2
Cat2
Sub1
Sub2
Item1
Item2
Sub3
Item1
Cat3
Cat4");
I created a Node class that could be helpfull. It is fast and has some extra properties, like:
Ancestors
Descendants
Siblings
Level of the node
Parent
Root
Etc.
You can write a simple binary tree , I wrote some Pseudo code beloew:
class TreeNode {
TreeNode Right;
TreeNode Left;
int id;
//...
}
class BinTree {
void Insert(TreeNode node)
{
while(true) {
if(node.id > target.id) {
if(target.Right != null) {
target = target.Right;
continue;
}
else {
target.Right = node;
break;
}
}
else if(node.id < target.id) {
if(target.Left != null) {
target = target.Left;
continue;
}
else {
target.Left = node;
break;
}
}
else {
throw new ArgumentException("Duplicated id");
}
}
}
TreeNode Search(int id)
{
TreeNode target = root;
while(target != null) {
if(id > target.id) {
target = target.Right;
}
else if(id < target.id) {
target = target.Left;
}
else {
return target;
}
}
return null;
}
}
But if your data count is very large, maybe AVL tree is more efficient

Categories