I was trying to solve one interview question, but for that I have to travel the binary tree level by level. I have designed BinaryNode with having below variable
private object data;
private BinaryNode left;
private BinaryNode right;
Could someone please help to write the BreadthFirstSearch method inside my BinarySearchTree class?
Update: Thanks everyone for your inputs. So this was the interview question.
"Given a binary search tree, design an algorithm which creates a linked list of all the nodes at each depth (i.e., if you have a tree with depth D, you’ll have D linked lists)".
Here is my Method, let me know your expert comment.
public List<LinkedList<BNode>> FindLevelLinkList(BNode root)
{
Queue<BNode> q = new Queue<BNode>();
// List of all nodes starting from root.
List<BNode> list = new List<BNode>();
q.Enqueue(root);
while (q.Count > 0)
{
BNode current = q.Dequeue();
if (current == null)
continue;
q.Enqueue(current.Left);
q.Enqueue(current.Right);
list.Add(current);
}
// Add tree nodes of same depth into individual LinkedList. Then add all LinkedList into a List
LinkedList<BNode> LL = new LinkedList<BNode>();
List<LinkedList<BNode>> result = new List<LinkedList<BNode>>();
LL.AddLast(root);
int currentDepth = 0;
foreach (BNode node in list)
{
if (node != root)
{
if (node.Depth == currentDepth)
{
LL.AddLast(node);
}
else
{
result.Add(LL);
LL = new LinkedList<BNode>();
LL.AddLast(node);
currentDepth++;
}
}
}
// Add the last linkedlist
result.Add(LL);
return result;
}
A breadth first search is usually implemented with a queue, a depth first search using a stack.
Queue<Node> q = new Queue<Node>();
q.Enqueue(root);
while(q.Count > 0)
{
Node current = q.Dequeue();
if(current == null)
continue;
q.Enqueue(current.Left);
q.Enqueue(current.Right);
DoSomething(current);
}
As an alternative to checking for null after dequeuing you can check before adding to the Queue. I didn't compile the code, so it might contain some small mistakes.
A fancier (but slower) version that integrates well with LINQ:
public static IEnumerable<T> BreadthFirstTopDownTraversal<T>(T root, Func<T, IEnumerable<T>> children)
{
var q = new Queue<T>();
q.Enqueue(root);
while (q.Count > 0)
{
T current = q.Dequeue();
yield return current;
foreach (var child in children(current))
q.Enqueue(child);
}
}
Which can be used together with a Children property on Node:
IEnumerable<Node> Children { get { return new []{ Left, Right }.Where(x => x != null); } }
...
foreach(var node in BreadthFirstTopDownTraversal(root, node => node.Children))
{
...
}
var queue = new Queue<BinaryNode>();
queue.Enqueue(rootNode);
while(queue.Any())
{
var currentNode = queue.Dequeue();
if(currentNode.data == searchedData)
{
break;
}
if(currentNode.Left != null)
queue.Enqueue(currentNode.Left);
if(currentNode.Right != null)
queue.Enqueue(currentNode.Right);
}
using DFS approach: The tree traversal is O(n)
public class NodeLevel
{
public TreeNode Node { get; set;}
public int Level { get; set;}
}
public class NodeLevelList
{
private Dictionary<int,List<TreeNode>> finalLists = new Dictionary<int,List<TreeNode>>();
public void AddToDictionary(NodeLevel ndlvl)
{
if(finalLists.ContainsKey(ndlvl.Level))
{
finalLists[ndlvl.Level].Add(ndlvl.Node);
}
else
{
finalLists.Add(ndlvl.Level,new List<TreeNode>(){ndlvl.Node});
}
}
public Dictionary<int,List<TreeNode>> GetFinalList()
{
return finalLists;
}
}
The method that does traversal:
public static void DFSLevel(TreeNode root, int level, NodeLevelList nodeLevelList)
{
if(root == null)
return;
nodeLevelList.AddToDictionary(new NodeLevel{Node = root, Level = level});
level++;
DFSLevel(root.Left,level,nodeLevelList);
DFSLevel(root.Right,level,nodeLevelList);
}
Related
I have this binary search tree with Node class and I need to write mapping and filtering method for it but I have no clue how can I go through the whole tree. My every attempt to go through it skipped almost half of the tree.
public class BST<T> where T:IComparable<T>
{
public class Node
{
public T value { get; }
public Node left;
public Node right;
public Node(T element)
{
this.value = element;
left = null;
right = null;
}
}
private Node root;
private void add(T element)
{
if (root == null)
root = new Node(element);
else
{
add(element, root);
}
}
public void add(T element, Node leaf)
{
if(element.CompareTo(leaf.value) > 0)
{
if (leaf.right == null)
leaf.right = new Node(element);
else
add(element,leaf.right);
}
else
{
if (leaf.left == null)
leaf.left = new Node(element);
else
add(element, leaf.left);
}
}
}
I have no clue how can I go through the whole tree
There are many ways to do that. One is to make your class iterable.
For that you can define the following method on your Node class:
public IEnumerator<T> GetEnumerator()
{
if (left != null) {
foreach (var node in left) {
yield return node;
}
}
yield return value;
if (right != null) {
foreach (var node in right) {
yield return node;
}
}
}
And delegate to it from a similar method on your BST class:
public IEnumerator<T> GetEnumerator()
{
if (root != null) {
foreach (var node in root) {
yield return node;
}
}
}
Now you can write code like this:
var tree = new BST<int>();
tree.add(4);
tree.add(2);
tree.add(3);
tree.add(6);
tree.add(5);
foreach (var value in tree) {
Console.WriteLine(value);
}
I need to write mapping and filtering method for it
It depends on what you want the result of a mapping/filtering function to be. If it is just a sequence of values, the above should be simple to adapt. If a new tree should be created with the mapped/filtered values, then feed these values back into a new tree (calling its add), or (in case of mapping) use the same recursive pattern of the above methods to create a new method that does not do yield, but creates a new tree while iterating the existing nodes, so the new tree has the same shape, but with mapped values.
This is an interview question, but I don't if there's a best solution for it.
Question: Write a function (in C# or C++) to merge two already sorted linked lists. Given a data structure:
C++:
class Node
{
public:
int data;
Node* next;
};
C#:
class Node
{
public int data;
public Node next;
};
Implement the function:
In C++:
Node* Merge (Node* head1, Node* head2)
{
…
}
In C#:
Node Merge (Node head1, Node head2)
{
…
}
It takes in two already sorted linked lists (in ascendant order) and is supposed to merge them into a single sorted linked list (in ascendant order) and returns the new head. The 2 lists might have nodes with identical data (the int value). We expect the result list doesn’t have identical data.
My solution:
Node Merge(Node head1, Node head2)
{
Node merged = head1;
// Both lists are empty
if (head1 == null && head2 == null)
{
return null;
}
// List 1 is empty
else if (head1 == null && head2 != null)
{
return head2;
}
// List 2 is empty
else if (head2 == null && head1 != null)
{
return head1;
}
// Both lists are not empty
else
{
Node cursor1 = head1;
Node cursor2 = head2;
if (cursor1.next.data > cursor2.data)
{
Node temp = cursor1;
cursor1 = cursor2;
cursor2 = temp;
}
// Add all elements from list 2 to list 1
while (cursor1.next != null && cursor2 != null)
{
if (cursor1.next.data < cursor2.data)
{
cursor1 = cursor1.next;
}
else
{
Node temp1 = cursor1.next;
Node temp2 = cursor2.next;
cursor1.next = cursor2;
cursor2.next = temp1;
cursor1 = cursor1.next;
cursor2 = temp2;
}
}
if (cursor1.next == null)
{
cursor1.next = cursor2;
}
}
// Remove duplicates
head1 = merged;
while (head1.next != null)
{
if (head1.data < head1.next.data)
{
head1 = head1.next;
}
else if (head1.data == head1.next.data)
{
head1.next = head1.next.next;
}
}
return merged;
}
Please give some comments and let me know your smart and good solution. Thank you!
After making sure that I was allowed to use the framework that goes with C#, this is what I would have done.
Given this linked list class (same as yours but using properties)
class Node
{
public int Data { get; set; }
public Node Next { get; set; }
}
Create an IEnumerator for the list
class NodeEnumerator : IEnumerator<int>
{
private Node _current_node;
public NodeEnumerator(Node first) {
_current_node = new Node { Data = 0, Next = first };
}
public int Current {
get { return _current_node.Data; }
}
object IEnumerator.Current {
get { return Current; }
}
public bool MoveNext() {
if (_current_node == null) {
return false;
}
_current_node = _current_node.Next;
return _current_node != null;
}
public void Reset() {
throw new NotSupportedException();
}
public void Dispose() {
}
}
Create the corresponding IEnumerable
class EnumerableNode : IEnumerable<int>
{
private Node _first;
public EnumerableNode(Node first) {
_first = first;
}
public IEnumerator<int> GetEnumerator() {
return new NodeEnumerator(_first);
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
Then use the awesome functions available to me in exchange for this little effort, namely Concat and Distinct
class Program
{
static void Main(string[] args) {
var list1 = new EnumerableNode(
new Node { Data = 1, Next =
new Node { Data = 2, Next =
new Node { Data = 3, Next = null }}});
var list2 = new EnumerableNode(
new Node { Data = 2, Next =
new Node { Data = 3, Next =
new Node { Data = 4, Next = null }}});
var merged = list1.Concat(list2).Distinct();
Console.WriteLine(String.Join(",", list1));
Console.WriteLine(String.Join(",", list2));
Console.WriteLine(String.Join(",", merged));
Console.ReadLine();
}
}
Output
1,2,3
2,3,4
1,2,3,4
The interviewer was probably looking for algorithmics (like your solution), but I think this is more life-like, more elegant, and still shows problem-solving skills, as well as knowledge of the framework and the general concept of enumerators. It works exactly the same in Java, Python and Ruby (and many others I'm sure). I have no idea how it would translate to C++ though.
You might wanna check out how std::merge is implemented:
http://www.cplusplus.com/reference/algorithm/merge/
How do I do a depth first search using a Queue in c#?
The following is my datastructure:
public class Node
{
public string Name{get;set}
public IEnumerable<Node> Children{get;set;}
}
Now I have a collection of Node object each with children, which again has children and so on.
I want to access each node and convert it into a different form.
Something like the below:
public IEnumerable<IContent> BuildContentFrom(IEnumerable<Node> nodes)
{
var queue = new Queue<Node>(nodes);
while (queue.Any())
{
var next = queue.Dequeue();
yield return BuildContentFromSingle(next);
foreach (var child in next.Children)
{
queue.Enqueue(child);
}
}
}
public IContent BuildContentFromSingle(Node node)
{
var content = _contentFactory.Create(node);
return content;
}
The above does not give me depth first for some reason. Can you please help?
Depth-first search is implemented using a LIFO data structure, so you 'd need to swap the Queue for a Stack. Using a FIFO structure like a queue gives you BFS instead.
you can do it recursively
public IEnumerable<IContent> BuildContentFrom(IEnumerable<Node> nodes) {
foreach(var node in nodes){
yield node;
foreach(var c in BuildContentFrom(node.children)){
yield c;
}
}
}
This might become a problem with n-trees when n is large and/or the tree deep.
in which case you could use an accumulator
public IEnumerable<IContent> BuildContentFrom(IEnumerable<Node> nodes) {
if(!nodes.Any()) return Enumerable.Empty<IContent>();
var acc = new List<IContent>();
BuildContentFrom(nodes);
}
public IEnumerable<IContent> BuildContentFrom(IEnumerable<Node> nodes,
IList<IContent> acc) {
foreach(var node in nodes){
acc.Add(BuildContentFromSingle(node));
if(node.children.Any()) BuildContentFrom(node.children, acc);
}
}
Which is now tail recursive and if the compiler optimizes for that (a setting for C# as far as I remember) you will have no stack issues even with large trees.
Alternatively you can use a stack to collect the work you still need to perform
public IEnumerable<IContent> BuildContentFrom(IEnumerable<Node> nodes)
{
var stack= new Stack<Node>(nodes);
while (stack.Any())
{
var next = stack.Pop();
yield return BuildContentFromSingle(next);
foreach (var child in next.Children)
{
stack.push(child);
}
}
}
As an alternative, you could consider flattening the structure using recursion. Here's an example with a binary tree. It demonstrates a depth-first flattening traversal.
using System;
using System.Collections.Generic;
namespace Demo
{
public static class Program
{
static void Main(string[] args)
{
var tree = buildTree(5, true);
printTree1(tree);
Console.WriteLine("---------------------------------------------");
printTree2(tree);
}
// Print tree using direct recursion.
static void printTree1<T>(Node<T> tree)
{
if (tree != null)
{
Console.WriteLine(tree.Value);
printTree1(tree.Left);
printTree1(tree.Right);
}
}
// Print tree using flattened tree.
static void printTree2<T>(Node<T> tree)
{
foreach (var value in flatten(tree))
{
Console.WriteLine(value);
}
}
// Flatten tree using recursion.
static IEnumerable<T> flatten<T>(Node<T> root)
{
if (root == null)
{
yield break;
}
foreach (var node in flatten(root.Left))
{
yield return node;
}
foreach (var node in flatten(root.Right))
{
yield return node;
}
yield return root.Value;
}
static Node<string> buildTree(int depth, bool left)
{
if (depth > 0)
{
--depth;
return new Node<string>(buildTree(depth, true), buildTree(depth, false), "Node." + depth + (left ? ".L" : ".R"));
}
else
{
return new Node<string>(null, null, "Leaf." + (left ? "L" : "R"));
}
}
}
public sealed class Node<T>
{
public Node(Node<T> left, Node<T> right, T value)
{
_left = left;
_right = right;
_value = value;
}
public Node<T> Left { get { return _left; } }
public Node<T> Right { get { return _right; } }
public T Value { get { return _value; } }
private readonly Node<T> _left;
private readonly Node<T> _right;
private readonly T _value;
}
}
For your specific example, I think (without testing it) that you can do this:
public static IEnumerable<Node> Flatten(Node root)
{
foreach (var node in root.Children)
{
foreach (var child in Flatten(node))
{
yield return child;
}
}
yield return root;
}
Depending on whether you allow null nodes, you might need to add some null checking:
public static IEnumerable<Node> Flatten(Node root)
{
if (root != null)
{
foreach (var node in root.Children)
{
foreach (var child in Flatten(node))
{
if (child != null)
{
yield return child;
}
}
}
yield return root;
}
}
I have been struggling for days finding .NET Tree Data Structure, I have read many recomendation using C5 library, but I have yet find example for it.
I have read C5 documentation but didn't find example for it (I admit I haven't read all documentation page).
Edit: I need a Tree with basic functionality like search from parent to child node and vice versa.
If you need only tree datastructure, just define yours. (will loose less time)
public abstract class NodeAbstract
{
abstract NodeAbstract Left {get;set:}
abstract NodeAbstract Right {get;set:}
....
....
}
public class NodeConcrete : NodeAbstract
{
....
//implementation
}
If you only need the most basic functionality, then build your own data structure.
I did a quick implementation of a basic tree (directional edges and not necessarily binary tree), assuming you have a fixed root node. I also added methods for searching depth first and breadth first.
using System;
using System.Collections.Generic;
namespace TreeTest
{
class Program
{
static void Main(string[] args)
{
//Build example tree
Tree tree = new Tree();
Node a = new Node(2);
Node b = new Node(7);
Node c = new Node(2);
Node d = new Node(6);
Node e = new Node(5);
Node f = new Node(11);
Node g = new Node(5);
Node h = new Node(9);
Node i = new Node(4);
tree.rootNode = a;
a.Edges.Add(b);
b.Edges.Add(c);
b.Edges.Add(d);
d.Edges.Add(e);
d.Edges.Add(f);
a.Edges.Add(g);
g.Edges.Add(h);
h.Edges.Add(i);
//Find node scannin tree from top down
Node node = tree.FindByValueBreadthFirst(6);
Console.WriteLine(node != null ? "Found node" : "Did not find node");
//Find node scanning tree branch for branch.
node = tree.FindByValueDepthFirst(2);
Console.WriteLine(node != null ? "Found node" : "Did not find node");
Console.WriteLine("PRESS ANY KEY TO EXIT");
Console.ReadKey();
}
}
class Tree
{
public Node rootNode;
public Node FindByValueDepthFirst(int val)
{
return rootNode.FindRecursiveDepthFirst(val);
}
public Node FindByValueBreadthFirst(int val)
{
if (rootNode.Value == val)
return rootNode;
else
return rootNode.FindRecursiveBreadthFirst(val);
}
}
class Node
{
public int Value { get; set; }
public IList<Node> Edges { get; set; }
public Node(int val)
{
Value = val;
Edges = new List<Node>(2);
}
public Node FindRecursiveBreadthFirst(int val)
{
foreach (Node node in Edges)
{
if (node.Value == val)
return node;
}
foreach (Node node in Edges)
{
Node result = node.FindRecursiveBreadthFirst(val);
if (result != null)
return result;
}
return null;
}
public Node FindRecursiveDepthFirst(int val)
{
if (Value == val)
return this;
else
{
foreach (Node node in Edges)
{
Node result = node.FindRecursiveDepthFirst(val);
if (result != null)
return result;
}
return null;
}
}
}
}
I am trying to reverse a linked list. This is the code I have come up with:
public static void Reverse(ref Node root)
{
Node tmp = root;
Node nroot = null;
Node prev = null;
while (tmp != null)
{
//Make a new node and copy tmp
nroot = new Node();
nroot.data = tmp.data;
nroot.next = prev;
prev = nroot;
tmp = tmp.next;
}
root = nroot;
}
It is working well. Was wondering if it possible to avoid creating new node. Would like to have suggestions on this.
That question gets asked a lot. When I was asked it in my interviews many years ago, I reasoned as follows: a singly-linked list is essentially a stack. Reversing a linked list is therefore a trivial operation on stacks:
newList = emptyList;
while(!oldList.IsEmpty())
newList.Push(oldList.Pop());
Now all you have to do is implement IsEmpty and Push and Pop, which are one or two lines tops.
I wrote that out in about twenty seconds and the interviewer seemed somewhat perplexed at that point. I think he was expecting me to take about twenty minutes to do about twenty seconds work, which has always seemed odd to me.
Node p = root, n = null;
while (p != null) {
Node tmp = p.next;
p.next = n;
n = p;
p = tmp;
}
root = n;
Years ago I missed out on a hipster-L.A.-entertainment-company ASP.NET MVC developer position because I could not answer this question :( (It's a way to weed out non-computer-science majors.) So I am embarrassed to admit that it took me way too long to figure this out in LINQpad using the actual LinkedList<T>:
var linkedList = new LinkedList<int>(new[]{1,2,3,4,5,6,7,8,9,10});
linkedList.Dump("initial state");
var head = linkedList.First;
while (head.Next != null)
{
var next = head.Next;
linkedList.Remove(next);
linkedList.AddFirst(next.Value);
}
linkedList.Dump("final state");
The read-only LinkedListNode<T>.Next property is what makes LinkedList<T> so important here. (Non-comp-sci people are encouraged to study the history of Data Structures---we are supposed to ask the question, Where does the linked list come from---why does it exist?)
You don't need to make a copy. Some pseudo code:
prev = null;
current = head;
next = current->next;
(while next != null)
current->next=prev
prev=current
current=next
next=current->next
This performed pretty well on Leetcode.
public ListNode ReverseList(ListNode head) {
ListNode previous = null;
ListNode current = head;
while(current != null) {
ListNode nextTemp = current.next;
current.next = previous;
previous = current;
current = nextTemp;
}
return previous;
}
Why not just have the head point at the tail, the tail point at the head, and go through the list reversing the direction in which prev points?
If you're not using a head and a tail, just go through the list reversing the prev relationships, and then make head point at the one that had a null prev when you got to it.
public Node ReverseList(Node cur, Node prev)
{
if (cur == null) // if list is null
return cur;
Node n = cur.NextNode;
cur.NextNode = prev;
return (n == null) ? cur : ReverseList(n, cur);
}
Here a sample code to reverse a linked list.
using System;
class Program
{
static void Main(string[] args)
{
LinkItem item = generateLinkList(5);
printLinkList(item);
Console.WriteLine("Reversing the list ...");
LinkItem newItem = reverseLinkList(item);
printLinkList(newItem);
Console.ReadLine();
}
static public LinkItem generateLinkList(int total)
{
LinkItem item = new LinkItem();
for (int number = total; number >=1; number--)
{
item = new LinkItem
{
name = string.Format("I am the link item number {0}.", number),
next = (number == total) ? null : item
};
}
return item;
}
static public void printLinkList(LinkItem item)
{
while (item != null)
{
Console.WriteLine(item.name);
item = item.next;
}
}
static public LinkItem reverseLinkList(LinkItem item)
{
LinkItem newItem = new LinkItem
{
name = item.name,
next = null
};
while (item.next != null)
{
newItem = new LinkItem
{
name = item.next.name,
next = newItem
};
item = item.next;
}
return newItem;
}
}
class LinkItem
{
public string name;
public LinkItem next;
}
linked list reversal recursive
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ReverseLinkedList
{
class Program
{
static void Main(string[] args)
{
Node head = null;
LinkedList.Append(ref head, 25);
LinkedList.Append(ref head, 5);
LinkedList.Append(ref head, 18);
LinkedList.Append(ref head, 7);
Console.WriteLine("Linked list:");
LinkedList.Print(head);
Console.WriteLine();
Console.WriteLine("Reversed Linked list:");
LinkedList.Reverse(ref head);
LinkedList.Print(head);
Console.WriteLine();
Console.WriteLine("Reverse of Reversed Linked list:");
LinkedList.ReverseUsingRecursion(head);
head = LinkedList.newHead;
LinkedList.PrintRecursive(head);
}
public static class LinkedList
{
public static void Append(ref Node head, int data)
{
if (head != null)
{
Node current = head;
while (current.Next != null)
{
current = current.Next;
}
current.Next = new Node();
current.Next.Data = data;
}
else
{
head = new Node();
head.Data = data;
}
}
public static void Print(Node head)
{
if (head == null) return;
Node current = head;
do
{
Console.Write("{0} ", current.Data);
current = current.Next;
} while (current != null);
}
public static void PrintRecursive(Node head)
{
if (head == null)
{
Console.WriteLine();
return;
}
Console.Write("{0} ", head.Data);
PrintRecursive(head.Next);
}
public static void Reverse(ref Node head)
{
if (head == null) return;
Node prev = null, current = head, next = null;
while (current.Next != null)
{
next = current.Next;
current.Next = prev;
prev = current;
current = next;
}
current.Next = prev;
head = current;
}
public static Node newHead;
public static void ReverseUsingRecursion(Node head)
{
if (head == null) return;
if (head.Next == null)
{
newHead = head;
return;
}
ReverseUsingRecursion(head.Next);
head.Next.Next = head;
head.Next = null;
}
}
public class Node
{
public int Data = 0;
public Node Next = null;
}
}
}
Complexity O(n+m). Assuming head is the start node:
List<Node>Nodes = new List<Node>();
Node traverse= root;
while(traverse!=null)
{
Nodes.Add(traverse);
traverse = traverse.Next;
}
int i = Nodes.Count - 1;
root = Nodes[i];
for(; i>0; i--)
{
Nodes[i].Next = Nodes[i-1];
}
Nodes[0].Next=null;
In case you want a ready-made efficient implementation, I created an alternative to LinkedList that supports enumeration and reverse operations. https://github.com/NetFabric/NetFabric.DoubleLinkedList
public class Node<T>
{
public T Value { get; set; }
public Node<T> Next { get; set; }
}
public static Node<T> Reverse<T>(Node<T> head)
{
Node<T> tail = null;
while(head!=null)
{
var node = new Node<T> { Value = head.Value, Next = tail };
tail = node;
head = head.Next;
}
return tail;
}
The definition of ref is unnecessary because if you make the node as a reference type, it is OK to do:
public static void Reverse(Node root)
Also, the beauty of the interview question is less consumption of memory and in place reversal. Maybe a recursive way of doing it is also asked.