Trying to remove a node and save it again c# - c#

I have a program, and i want to remove a node from the tree. Ok, i can remove, but when i want to save it again it shows me a error.
public void InsertNode(string value)
{
root = InsertNode(value, root);
}
private Node InsertNode(string value, Node node)
{
if (node == null)
{
node = new Node(value, null, null);
}
else
{
if (node.value.CompareTo(value) > 0) ---- The error is in this line
{
node.lChild = InsertNode(value, node.lChild);
}
else
{
node.rChild = InsertNode(value, node.rChild);
}
}
return node;
}

Related

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

Binary Search Tree "stack" explanation

I have a very simple implemention of BST in C#. The code:
class Node
{
public int? value;
public Node parent;
public Node left;
public Node right;
public Node(int? value, Node parent = null)
{
this.value = value;
this.parent = parent;
}
}
class BST
{
public Node root;
public List<Node> tree = new List<Node>();
public BST(int? value = null)
{
if (value != null)
{
this.root = new Node(value);
this.tree.Add(this.root);
}
}
public Node insert(int value)
{
Node node = this.root;
if (node == null)
{
this.root = new Node(value);
this.tree.Add(this.root);
return this.root;
}
while (true)
{
if (value > node.value)
{
if (node.right != null)
{
node = node.right;
}
else
{
node.right = new Node(value, node);
node = node.right;
break;
}
}
else if (value < node.value)
{
if (node.left != null)
{
node = node.left;
}
else
{
node.left = new Node(value, node);
node = node.left;
break;
}
}
else
{
break;
}
}
return node;
}
}
class Program
{
static void Main()
{
BST superTree = new BST(15);
superTree.insert(14);
superTree.insert(25);
superTree.insert(2);
}
}
My Question is regarding the "Insert" method of the BST class.
How exactly its "return" work when I just call it in the main method?
How does it know to put that "node" on the "left"? I am not referencing "root.left" anywhere but somehow it gets properly inserted.
I realized at some point that some kind of recursion occurs there, but its been like 6 hours and I still can't understand how this method properly works.
I appreaciate any explanation of that "insert" method.Thanks.
Node node = this.root;
Your code always starts with the root, because of this line. It's only after node is no longer null that node be re-assigned to something other than root. The rest of the code works on node.left, but because your code begins with root as above, node.left is actually referencing root at the start.

reverse a linked list in a recursive function c#

I'm having problems trying to write a reverse recursive method for a LinkedList class I created in C#.
The LinkedList has 2 pointers in it one for the head and the other for the tail:
public class Node
{
public object data;
public Node next;
public Node(object Data)
{
this.data = Data;
}
}
public class LinkedList
{
Node head;
Node tail;
public void Add(Node n)
{
if (head == null)
{
head = n;
tail = head;
}
else
{
tail.next = n;
tail = tail.next;
}
}
Now, the recursive reverse function goes like this:
public void reverse_recursive()
{
Node temp_head = head;
if (temp_head == tail)
{
return;
}
while (temp_head != null)
{
if (temp_head.next == tail)
{
tail.next = temp_head;
tail = temp_head;
reverse_recursive();
}
temp_head = temp_head.next;
}
}
I'm having 2 troubles with it: first, a logic problem, I know that head doesn't point to the first node after the reverse. The second problem is that i probably do something wrong with the null pointer so the program crashes.
I also give you the main program:
class Program
{
static void Main(string[] args)
{
LinkedList L = new LinkedList();
L.Add(new Node("first"));
L.Add(new Node("second"));
L.Add(new Node("third"));
L.Add(new Node("forth"));
L.PrintNodes();
L.reverse_recursive();
L.PrintNodes();
Console.ReadLine();
}
}
Thank you for helping!!
public void Reverse()
{
this.Reverse(this.head);
}
private void Reverse(Node node)
{
if (node != null && node.next != null)
{
// Create temporary references to the nodes,
// because we will be overwriting the lists references.
Node next = node.next;
Node afterNext = node.next.next;
Node currentHead = this.head;
// Set the head to whatever node is next from the current node.
this.head = next;
// Reset the next node for the new head to be the previous head.
this.head.next = currentHead;
// Set the current nodes next node to be the previous next nodes next node :)
node.next = afterNext;
// Keep on trucking.
this.Reverse(node);
}
else
{
this.tail = node;
}
}
public void reverse()
{
reverse_recursive(tail);
Node tmp = tail;
tail = head;
head = tmp;
}
public void reverse_recursive(Node endNode)
{
Node temp_head = head;
if (temp_head == endNode)
{
return;
}
while (temp_head != null)
{
if (temp_head.next == endNode)
{
break;
}
temp_head = temp_head.next;
}
endNode.next = temp_head;
temp_head.next = null;
reverse_recursive(temp_head);
}
See also this
Another option over here.
class Program{
static void Main(string[] args)
{
LinkedList L = new LinkedList();
L.Add(new Node("first"));
L.Add(new Node("second"));
L.Add(new Node("third"));
L.Add(new Node("forth"));
L.PrintNodes();
L.reverse_recursive();
Console.WriteLine("---------------------");
L.PrintNodes();
Console.ReadLine();
}
}
public class Node
{
public object data;
public Node next;
public Node(object Data)
{
this.data = Data;
}
}
public class LinkedList
{
Node head;
Node tail;
public void Add(Node n)
{
if (head == null)
{
head = n;
tail = head;
}
else
{
tail.next = n;
tail = tail.next;
}
}
public void PrintNodes()
{
Node temp = head;
while (temp != null)
{
Console.WriteLine(temp.data);
temp = temp.next;
}
}
private LinkedList p_reverse_recursive(Node first)
{
LinkedList ret;
if (first.next == null)
{
Node aux = createNode(first.data);
ret = new LinkedList();
ret.Add(aux);
return ret;
}
else
{
ret = p_reverse_recursive(first.next);
ret.Add(createNode(first.data));
return ret;
}
}
private Node createNode(Object data)
{
Node node = new Node(data);
return node;
}
public void reverse_recursive()
{
if (head != null)
{
LinkedList aux = p_reverse_recursive(head);
head = aux.head;
tail = aux.tail;
}
}
}
Hope it helps
A second variant
private void p_reverse_recursive2(Node node)
{
if (node != null)
{
Node aux = node.next;
node.next = null;
p_reverse_recursive2(aux);
if (aux != null)
aux.next = node;
}
}
public void reverse_recursive()
{
if (head != null)
{
Node aux = head;
head = tail;
tail = aux;
p_reverse_recursive2(tail);
}
}
Variation on a theme...
public Node Reverse(Node head)
{
if(head == null)
{
return null;
}
Node reversedHead = null;
ReverseHelper(head, out reversedHead);
return reversedHead;
}
public Node ReverseHelper(Node n, out Node reversedHead)
{
if(n.Next == null)
{
reversedHead = n;
return n;
}
var reversedTail = ReverseHelper(n.Next, out reversedHead);
reversedTail.Next = n;
n.Next = null;
return n;
}
}
I was just playing with similar brain teaser with the only difference that LinkedList class only has a definition for head and all the rest of the nodes are linked there. So here is my quick and dirty recursive solution:
public Node ReverseRecursive(Node root)
{
Node temp = root;
if (root.next == null)
return root;
else
root = ReverseRecursive(root.next);
temp.next = null;
Node tail = root.next;
if (tail == null)
root.next = temp;
else
while (tail != null)
{
if (tail.next == null)
{
tail.next = temp;
break;
}
else
tail = tail.next;
}
return root;
}

how to find a NodeData in tree of Nodes?

I have a Node structure as below,this Node has stringdata and list of nodes as it's children. I wanted to search a data in this tree
I wrote a recursive function FindNode(Node intree,string target)
public class Node
{
public string Data;
public List<Node> Children = new List<Node>();
//some code
public Node(string r)
{
this.Data = r;
}
public string getData()
{
return this.Data;
}
//some code
public List<Node> getchildren()
{
return this.Children;
}
//some code
}
target is the string which I want to find and the intree is the begining of the tree(ROOT)
I have problem after while loop what should I return after that?
If I am wrong how should I write it?
public Node FindNode(Node intree,string target)
{
if(intree.getData()==target)
return intree;
else
{
while(intree.getchildren()!=null)
{
foreach(Node n in intree.getchildren())
{
FindNode(n,target);
}
}
}
}
Use this one:
public Node FindNode(Node intree,string target)
{
if(intree.getData()==target)
return intree;
else
{
foreach(Node n in intree.getchildren())
{
Node node = FindNode(n,target) ; //CHECK FOR RETURN
if(node != null)
return node;
}
}
return null;
}
The difference is that I checked for return of FindNode method, and if it's not null, return result.
Just note that in case of dupplicated nodes in the tree (nodes with the same string) it will return first occuarance.
Given that there could be more than one match in the tree you would be better off returning an IEnumerable<Node>. Also you don't need to put those odd get methods in there. And finally did you mean to only search leaf nodes or did you want to search all nodes (the else statement)?
public IEnumerable<Node> FindNode(Node intree,string target)
{
if(intree.Data ==target)
yield return intree;
foreach (var node in intree.Children.SelectMany(c => FindNode(c, target))
yield return node;
}
If you want the first matching node, just call First() on the result. If you want to make sure there is only one, call Single() on it.
I would recommend you to return null and apply check where you are calling this method that if null is returned then it means no node found. Code is as follow
public static Node FindNode(Node intree, string target)
{
if (intree.getData() == target)
return intree;
foreach (Node node in intree.getchildren())
{
Node toReturn = FindNode(node, target);
if (toReturn != null) return toReturn;
}
return null;
}
public Node FindNodeRecursively(Node parentNode, string keyword)
{
if(parentNode.getData() == keyword)
{
return parentNode;
}
else
{
if(parentNode.Children != null)
{
foreach(var node in parentNode.Children)
{
var temp = FindNodeRecursively(node, keyword);
if(temp != null)
return temp;
}
}
return null;
}
}

Categories