Loop detection in LinkedList using C# - c#

In the interview question, "Implement an algorithm which detects for presence of the loop.". For example, the linked list has a loop, like:
0--->1---->2---->3---->4---->5---->6
▲ |
| ▼
11<—-22<—-12<—-9<—-8
Using Floyd's cycle detection, this problem can be solved by using a fast & slow pointer. So should I try comparing
a. Link's node values, i.e.
if (fast.data == slow.data)
break;
where fast and slow are of type Link
class Link
{
int IData {get; set;}
Link Next {get; set;}
}
OR
b. Are they pointing to same reference, i.e. if (fast == slow)
Thanks.

You should only be comparing the nodes themselves. After all, it's reasonable to have a linked list with repeated data in, without it actually having a cycle.
I would call them nodes rather than links too. A link is simply the reference from one node to the next or previous one - in particular, there's no data associated with a link, only with a node.

Hope this helps... It might be naive but it works...
using System;
namespace CSharpTestTemplates
{
class LinkedList
{
Node Head;
public class Node
{
public int value;
public Node NextNode;
public Node(int value)
{
this.value = value;
}
}
public LinkedList(Node head)
{
this.Head = head;
}
public Boolean hasLoop()
{
Node tempNode = Head;
Node tempNode1 = Head.NextNode;
while(tempNode!=null && tempNode1!=null){
if(tempNode.Equals(tempNode1)){
return true;
}
if ((tempNode1.NextNode != null) && (tempNode.NextNode != null))
{
tempNode1 = tempNode1.NextNode.NextNode;
tempNode = tempNode.NextNode;
}
else
{
return false;
}
}
return false;
}
public static void Main()
{
Node head = new Node(1);
LinkedList ll = new LinkedList(head);
Node node2 = new Node(2);
Node node3 = new Node(3);
Node node4 = new Node(4);
Node node5 = new Node(5);
Node node6 = new Node(6);
head.NextNode = node2;
node2.NextNode = node3;
node3.NextNode = node4;
node4.NextNode = node5;
node5.NextNode = node6;
node6.NextNode = null;
Console.WriteLine(ll.hasLoop());
Console.Read();
}
}
}

Related

BInary Search Tree iterator c# without parent property

I recently started making a Binary Search Tree in C# in order to practice. After completing this task I decided to implement ICollection<T> so that my tree can be used with a foreachand just in general in order for me to practice.
I've constructed my classes in such a way that I have a Node<T> class and a BinarySearchTree<T> class that contains a Node<T> a Count integer and a IsReadOnly boolean. This is my Node Class:
internal class Node<T>: INode<T> where T: IComparable<T>
{
public Node<T> RightChildNode { get; set; }
public Node<T> LeftChildNode { get; set; }
public T Key { get; set; }
//some methods go here
}
and this is my BST class:
public class BinarySearchTree<T>: ICollection<T> where T: IComparable<T>
{
internal Node<T> Root { get; set; }
public int Count { get; private set; }
public bool IsReadOnly => false;
//some methods go here
}
Now in order to implement ICollection<T> i obviously need an enumerator which I have (partly) implemented as such:
internal class BinarySearchTreeEnumerator<T> : IEnumerator<T> where T: IComparable<T>
{
private BinarySearchTree<T> _parentTree;
private BinarySearchTree<T> _currentTree;
private Node<T> _currentNode => _currentTree.Root;
private T _currentKey;
public T Current => _currentNode.Key;
/// <summary>
/// generic constructor
/// </summary>
/// <param name="tree"></param>
public BinarySearchTreeEnumerator(BinarySearchTree<T> tree)
{
this._parentTree = tree;
}
object IEnumerator.Current => Current;
void IDisposable.Dispose(){}
//pls
public bool MoveNext()
{
if (_currentTree is null)
{
_currentTree = _parentTree;
}
var leftSubtree = this._currentTree.GetLeftSubtree();
var rightSubtree = this._currentTree.GetRightSubtree();
if (!(leftSubtree is null))
{
this._currentTree = leftSubtree;
}
else if (!(rightSubtree is null))
{
this._currentTree = rightSubtree;
}
else
{
}
}
public void Reset()
{
_currentTree = _parentTree;
}
}
now my issue is quite obviously with the MoveNext() method. It doesn't work now because what it does is it just goes down the tree on the leftmost possible path and then gets stuck when it gets to the end of that path. I know I can fix this problem by adding a Parent property to my Node<T> class and then whenever I reach the end of a path in my tree I can just go one Node up and check if there's a different path... However this would mean completely changing my original class and I would prefer not to do that.
Is this just unavoidable? Is there any way to solve this issue without changing my Node<T> class in such a way?
Edit: I Made a thing but its not working :/
public bool MoveNext()
{
if (_currentNode is null)
{
this._currentNode = _parentTree.Root;
this._nodeStack.Push(_currentNode);
return true;
}
var leftNode = this._currentNode.LeftChildNode;
var rightNode = this._currentNode.RightChildNode;
if (!(leftNode is null))
{
this._currentNode = leftNode;
this._nodeStack.Push(_currentNode);
return true;
}
else if (!(rightNode is null))
{
this._currentNode = rightNode;
this._nodeStack.Push(_currentNode);
return true;
}
else
{
//current node does not have children
var parent = this._nodeStack.Pop();
do
{
if (parent is null)
{
return false;
}
} while (!(parent.RightChildNode is null));
this._currentNode = parent.RightChildNode;
this._nodeStack.Push(_currentNode);
return true;
}
}
It might be easier to use recursion to implement this; for example:
Recursive version (for balanced trees only)
public IEnumerator<T> GetEnumerator()
{
return enumerate(Root).GetEnumerator();
}
IEnumerable<T> enumerate(Node<T> root)
{
if (root == null)
yield break;
yield return root.Key;
foreach (var value in enumerate(root.LeftChildNode))
yield return value;
foreach (var value in enumerate(root.RightChildNode))
yield return value;
}
These are members of BinarySearchTree<T>.
Given the above implementation, then the following code:
BinarySearchTree<double> tree = new BinarySearchTree<double>();
tree.Root = new Node<double> {Key = 1.1};
tree.Root.LeftChildNode = new Node<double> {Key = 2.1};
tree.Root.RightChildNode = new Node<double> {Key = 2.2};
tree.Root.LeftChildNode.LeftChildNode = new Node<double> { Key = 3.1 };
tree.Root.LeftChildNode.RightChildNode = new Node<double> { Key = 3.2 };
tree.Root.RightChildNode.LeftChildNode = new Node<double> { Key = 3.3 };
tree.Root.RightChildNode.RightChildNode = new Node<double> { Key = 3.4 };
foreach (var value in tree)
{
Console.WriteLine(value);
}
produces this output:
1.1
2.1
3.1
3.2
2.2
3.3
3.4
WARNING: Stack space is limited to 1MB for a 32-bit process and 4MB for a 64-bit process, so using recursion is likely to run out of stack space if the tree is degenerate (badly unbalanced).
Non-recursive version
You can implement the non-recursive version fairly simply, like so:
IEnumerable<T> enumerate(Node<T> root)
{
var stack = new Stack<Node<T>>();
stack.Push(root);
while (stack.Count > 0)
{
var node = stack.Pop();
if (node == null)
continue;
yield return node.Key;
stack.Push(node.RightChildNode);
stack.Push(node.LeftChildNode);
}
}
This returns the elements in the same order as the recursive version.
Since this version will not run out of stack space even for a degenerate tree, it is preferable to the recursive version.
If you add to your enumerator a
private List<Node<T>> _currentParentNodes = new List<Node<T>>();
and use it like a stack, each time you go down a level you push the current node to currentParentNodes, each time you have to go up you pop the parent node from currentParentNodes, then all your problems will pop away :-)
Do you need a depth-first-search(DFS) approach? It has a recursive nature which is hard to save as a state (it uses the call stack).
Maybe consider the broad-first-search (BFS) approach, which is iterative. You'd only need a currentNode and a Queue.
The rule would be
current = Queue.poll();
For child in current
Queue.offer(child);
At init you would do
Queue.offer(rootNode);
I apologize for my poor formatting and syntax, mobile user here.
Andres

Linked List Implementation by Structure In C#()

I am implementing Linked List in C# so I use Two Approaches
First Approach
unsafe public struct Node
{
public int info;
public Node* link;
}
Here Is Add Node Method
public void AddNode( int a)
{
Node temp = new Node();
temp.info = a;
if (Head == null)
{
Head = Current = &temp;
}
else
{
(*Current).link = &temp;
Current = &temp;
}
}
When I run This Code It does not save memory means It create an instance of Node temp = new Node();Structure as long as it is inside AddNode Its memory is save but when I print It outside this method using Head its give me NullRefrenceException
Second Approach
By Using Class And Objects
public class Node
{
public int info;
public Node link;
}
class Linked_list
{
public Node Head;
public Node Current;
public void insert_element_linkedlist( int a)
{
Node temp = new Node();
temp.info = a;
if (Head == null)
{
Head = Current = temp;
}
else
{
Current.link = temp;
Current = temp;
}
}
}
The Second method is working perfectly means Every instance of temp node Node temp = new Node(); is save in memory .
Question :
Why It does not save structure instance ?
Sorry For My Sub Standard English.
The structure instance, being a value type, gets created on the stack, so when AddNode returns it is cleaned up and you are left with pointers to a random place in memory. Simply creating a pointer to a variable is not enough to keep it alive.

How do i write a method that removes specific object from linked list?

i didn't succeed to remove specific item from linked list,the method is - public void removeFromList(string itemtoremove, LinkedList List).
How do i write method that removes specific item from linked list?
my code is:
public class Node
{
public Node next; //saves the adress
public Person data; //saves the person
}
public class LinkedList
{
private Node head; //starts from the begging
public void AddFirst(Person data)
{
Node toAdd = new Node();
toAdd.data = data; // in data he saves the object
toAdd.next = head;
head = toAdd;
}
public void removeFromList(string itemtoremove, LinkedList List) //
{
Node current = head;
Node current1 = current.next;
while (current1 != null)
{
if (current1.data.instrument == itemtoremove)
???
}
}
}
Your method already has a problem before you even implement the algorithm. You are skipping the head node. You also don't need to pass the linked list in as a parameter to the instance method.
public void removeFromList(string itemtoremove)
{
Node previousNode = null;
Node current = head;
while (current != null) //starting with current1 would ignore the head node
{
// we found a match
if (current.data.instrument == itemtoremove){
// head node is treated slightly differently
if(current == head){
// set the next node to the new head
head = current.next;
// set to null so GC can clean it up
current = null;
return;
}
else {
//update the previous node's link
previousNode.next = current.next;
current = null;
return;
}
}
// move on to the next
previousNode = current;
current = current.next;
}
}

C# How to pool the objects of a node tree efficiently?

I have a node class that contains only value type properties, and one reference type: it's parent node. When performing tree searches, these nodes are created and destroyed hundreds of thousands of times in a very short time span.
public class Node
{
public Node Parent { get; set; }
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
public int D { get; set; }
}
The tree search looks something like this:
public static Node GetDepthFirstBest(this ITree tree, Node root)
{
Node bestNode = root;
float bestScore = tree.Evaluate(root);
var stack = new Stack<Node>();
stack.Push(root);
while(stack.Count > 0)
{
var current = stack.Pop();
float score = tree.Evaluate(current);
if (score > bestScore)
{
bestNode = current;
bestScore = score;
}
var children = tree.GetChildren(current);
foreach(var c in children) { stack.Push(c); }
}
return bestNode;
}
Because this is done in a Mono runtime that has a very old GC, I wanted to try and pool the node objects. However, I am at a loss on how to know when a node object is safe to return to the pool, since other nodes that are still in use might reference it as a parent. At the end of the search, the best node is returned and a list of nodes is formed by walking back through its ancestors. I have full control over how the nodes are created inside the tree, if that's useful.
What options could I try and implement?
So, fortunately, if you're doing a Depth-First-Search, which you appear to be, this is a bit easier. Any time you reach a leaf node, there are two possibilities: that leaf node is part of the current deepest tree, or it's not.
If it's not, that means it's safe to return this node to the pool. If it is, that means we can return any nodes in our old tree back to our pool that are not in our own ancestor chain.
Now, if we're not a leafnode, we don't know if we can be freed until after we've finished checking our children. then, once all our children are checked, we find out if any of our children said they were the current best. if so, we keep ourselves
this does mean we're doing quite a bit more checking.
Here's some sudo code:
List bestNodes;
bool evalNode(node, score)
{
if (childCount == 0)
{
if (score > bestScore)
{
bestScore = score;
bestNode = node;
bestNodes.Add(node);
return true;
}
else
{
freeNode(this);
return false;
}
}
else
{
bool inLongest = false;
foreach (child in children)
{
inLongest = evalNode(child, score + 1) || inLongest;
}
if (!inLongest)
{
freeNode(node);
}
else
{
free(bestNodes[score]);
bestNodes[score] = node;
}
return inLongest;
}
}
Try using the ref keyword if your node is a struct, this avoids copying the node every time you pass it through to a function.
Thus:
struct Node
{
object obj;
Node children;
}
public void DoStuffWithNode(ref Node pNode){...Logic...}

Bug in parallel tree printing method

Classes:
public class Tree
{
public Node RootNode { get; set; }
}
public class Node
{
public int Key { get; set; }
public object Value { get; set; }
public Node ParentNode { get; set; }
public List<Node> Nodes { get; set; }
}
Methods:
This method generates a tree.
private static int totalNodes = 0;
static Tree GenerateTree()
{
Tree t = new Tree();
t.RootNode = new Node();
t.RootNode.Key = 0;
t.RootNode.Nodes = new List<Node>();
Console.WriteLine(t.RootNode.Key);
List<Node> rootNodes = new List<Node>();
rootNodes.Add(t.RootNode);
while (totalNodes <= 100000)
{
List<Node> newRootNodes = new List<Node>();
foreach (var rootNode in rootNodes)
{
for (int j = 0; j < 3; j++)
{
totalNodes++;
Console.Write(string.Format(" {0}({1}) ", totalNodes, rootNode.Key));
Node childNode = new Node() {Key = totalNodes, Nodes = new List<Node>(), ParentNode = t.RootNode};
rootNode.Nodes.Add(childNode);
newRootNodes.Add(childNode);
}
Console.Write(" ");
}
Console.WriteLine();
rootNodes = newRootNodes;
}
return t;
}
This method is supposed to print a tree, but node is null in some case:
static void PrintTreeParallel(Node rootNode)
{
List<Node> rootNodes = new List<Node>();
List<Node> newRootNodes = new List<Node>();
rootNodes.Add(rootNode);
Console.WriteLine(rootNode.Key);
while (rootNodes.Count > 0)
{
newRootNodes = new List<Node>();
Parallel.ForEach(rootNodes, node =>
{
if (node != null)
{
Console.Write(string.Format(" {0} ", node.Key));
if (node.Nodes != null)
Parallel.ForEach(node.Nodes,
newRoot => { newRootNodes.Add(newRoot); });
}
else
{
//HOW CAN WE GET HERE?????
Debugger.Break();
Console.WriteLine(rootNodes.Count);
}
});
Console.WriteLine();
rootNodes = newRootNodes;
}
}
Execute:
static void Main(string[] args)
{
var t = GenerateTree();
Console.WriteLine("Tree generated");
PrintTreeParallel(t.RootNode);
Console.WriteLine("Tree printed paral");
Console.ReadLine();
}
Question:
What's wrong here?
Why node is null in some case?
And it happens only when there are a lot of generated nodes. For ex if there would be only 10 nodes everything is OK.
The problem is that you have this code:
Parallel.ForEach(node.Nodes, newRoot => { newRootNodes.Add(newRoot); });
Which allows multiple threads to add items to the newRootNodes list concurrently. As a commenter pointed out, List<T> is not thread-safe. What's probably happening is that one thread's Add is being interrupted by another thread's call to Add, which causes an internal index in the list to be incremented. That leaves a null value in one of the list's items.
Then, later in the loop you have:
rootNodes = newRootNodes;
Which puts the corrupted list as the list that's going to be iterated by the while.
You have a data race here:
Parallel.ForEach(node.Nodes,
newRoot => { newRootNodes.Add(newRoot); });
Adding to a list with multiple threads is not thread-safe and will cause undetermined behavior.
First try to run this part with a simple foreach and see if the problem goes away. Running two nested Parallel.ForEach statements is definitely a bizarre choice.
List<T> is indeed not thread safe, so rootNode.Nodes.Add(childNode); is dropping data in unpredictable ways.
Instead of using List<> use ConcurrentBag<> and it will all work. Note that ConcurrentBag<T> is unordered, but that is fine because you have no way of predicting the order from the threads anyway.

Categories