Fundamental Data Structures in C# - c#

I would like to know how people implement the following data structures in C# without using the base class library implementations:-
Linked List
Hash Table
Binary Search Tree
Red-Black Tree
B-Tree
Binomial Heap
Fibonacci Heap
and any other fundamental data structures people can think of!
I am curious as I want to improve my understanding of these data structures and it'd be nice to see C# versions rather than the typical C examples out there on the internet!

There's a series of MSDN articles on this subject. However, I haven't really read the text myself. I believe that the collections framework by .NET has a broken interface and cannot be extended very well.
There's also C5, a libray that I am investigating right now.
For the reason mentioned above, I've had the project to implement my own collections library for .NET but I've stopped this project after the first benchmark revealed that even a straightforward, non-thread-safe generic Vector implementation is slower than the native List<T>. Since I've taken care not to produce any inefficient IL code, this means that .NET is simply not suited (yet) for writing on-par replacements for intrinsic data structures, and that the .NET framework has to use some behind-the-scenes knowledge to optimize the builtin collection classes.

Here is a generic Binary Search Tree. The only thing I didn't do was implement IEnumerable<T> so you could traverse the tree using a enumerator. However that should be fairly straight forward.
Special thanks to Scott Mitchel for his BSTTree article, I used it as a reference on the delete method.
The Node Class:
class BSTNode<T> where T : IComparable<T>
{
private BSTNode<T> _left = null;
private BSTNode<T> _right = null;
private T _value = default(T);
public T Value
{
get { return this._value; }
set { this._value = value; }
}
public BSTNode<T> Left
{
get { return _left; }
set { this._left = value; }
}
public BSTNode<T> Right
{
get { return _right; }
set { this._right = value; }
}
}
And the actual Tree class:
class BinarySearchTree<T> where T : IComparable<T>
{
private BSTNode<T> _root = null;
private int _count = 0;
public virtual void Clear()
{
_root = null;
_count = 0;
}
public virtual int Count
{
get { return _count; }
}
public virtual void Add(T value)
{
BSTNode<T> newNode = new BSTNode<T>();
int compareResult = 0;
newNode.Value = value;
if (_root == null)
{
this._count++;
_root = newNode;
}
else
{
BSTNode<T> current = _root;
BSTNode<T> parent = null;
while (current != null)
{
compareResult = current.Value.CompareTo(newNode.Value);
if (compareResult > 0)
{
parent = current;
current = current.Left;
}
else if (compareResult < 0)
{
parent = current;
current = current.Right;
}
else
{
// Node already exists
throw new ArgumentException("Duplicate nodes are not allowed.");
}
}
this._count++;
compareResult = parent.Value.CompareTo(newNode.Value);
if (compareResult > 0)
{
parent.Left = newNode;
}
else
{
parent.Right = newNode;
}
}
}
public virtual BSTNode<T> FindByValue(T value)
{
BSTNode<T> current = this._root;
if (current == null)
return null; // Tree is empty.
else
{
while (current != null)
{
int result = current.Value.CompareTo(value);
if (result == 0)
{
// Found the corrent Node.
return current;
}
else if (result > 0)
{
current = current.Left;
}
else
{
current = current.Right;
}
}
return null;
}
}
public virtual void Delete(T value)
{
BSTNode<T> current = this._root;
BSTNode<T> parent = null;
int result = current.Value.CompareTo(value);
while (result != 0 && current != null)
{
if (result > 0)
{
parent = current;
current = current.Left;
}
else if (result < 0)
{
parent = current;
current = current.Right;
}
result = current.Value.CompareTo(value);
}
if (current == null)
throw new ArgumentException("Cannot find item to delete.");
if (current.Right == null)
{
if (parent == null)
this._root = current.Left;
else
{
result = parent.Value.CompareTo(current.Value);
if (result > 0)
{
parent.Left = current.Left;
}
else if (result < 0)
{
parent.Right = current.Left;
}
}
}
else if (current.Right.Left == null)
{
if (parent == null)
this._root = current.Right;
else
{
result = parent.Value.CompareTo(current.Value);
if (result > 0)
{
parent.Left = current.Right;
}
else if (result < 0)
{
parent.Right = current.Right;
}
}
}
else
{
BSTNode<T> furthestLeft = current.Right.Left;
BSTNode<T> furthestLeftParent = current.Right;
while (furthestLeft.Left != null)
{
furthestLeftParent = furthestLeft;
furthestLeft = furthestLeft.Left;
}
furthestLeftParent.Left = furthestLeft.Right;
furthestLeft.Left = current.Left;
furthestLeft.Right = current.Right;
if (parent != null)
{
result = parent.Value.CompareTo(current.Value);
if (result > 0)
{
parent.Left = furthestLeft;
}
else if (result < 0)
{
parent.Right = furthestLeft;
}
}
else
{
this._root = furthestLeft;
}
}
this._count--;
}
}
}

I would recommend two resources for the data structures you mention:
First, there is the .NET Framework Source Code (information can be found on ScottGu's blog here).
Another useful resource is the Wintellect's Power Collections found on Codeplex here.
Hope this helps!

NGenerics
"A class library providing generic data structures and algorithms not implemented in the standard .NET framework."

Check out Rotor 2 or use reflector too see how Microsoft did it!!!
also you can check Microsoft reference source

Related

Remove function of BST in C#

I am trying to write the remove function for BST in C#. I have some NUnit tests that need to pass. All of them pass except two. I have two scenarios for which the test fails.
I need to remove 10 for these two trees. But it's failing:
100, 10, 5
100, 10, 20
So I'm guessing my code doesn't splice the 10 out. And the error is in the RemoveNonRootNode method. And specifically with the "else if" statements that are looking at 1 child situation.
Here is my code. I appreciate some help!
public class BST
{
private BSTNode m_top;
private class BSTNode
{
private int m_data;
private BSTNode m_left;
private BSTNode m_right;
public int Data
{
get { return m_data; }
set { m_data = value; }
}
public BSTNode Left
{
get { return m_left; }
set { m_left = value; }
}
public BSTNode Right
{
get { return m_right; }
set { m_right = value; }
}
public BSTNode(int data)
{
m_data = data;
}
}
public void AddValue(int v)
{
if (m_top == null)
{
m_top = new BSTNode(v);
}
else
{
BSTNode cur = m_top;
while (true)
{
if (v < cur.Data)
{
if (cur.Left == null)
{
cur.Left = new BSTNode(v);
return;
}
else
cur = cur.Left;
}
else if (v > cur.Data)
{
if (cur.Right == null)
{
cur.Right = new BSTNode(v);
return;
}
else
cur = cur.Right;
}
else
throw new DuplicateValueException("Value " + v + " is already in the tree!");
}
}
}
public void Print()
{
Console.WriteLine("=== Printing the tree ===");
if (m_top == null)
Console.WriteLine("Empty tree!");
else
PrintInternal(m_top);
}
private void PrintInternal(BSTNode cur)
{
if (cur.Left != null)
PrintInternal(cur.Left);
Console.WriteLine(cur.Data);
if (cur.Right != null)
PrintInternal(cur.Right);
}
public bool Find(int target)
{
return FindNode(target) != null;
}
private BSTNode FindNode(int target)
{
BSTNode cur = m_top;
while (cur != null)
{
if (cur.Data == target)
return cur;
else if (target < cur.Data)
cur = cur.Left;
else if (target > cur.Data)
cur = cur.Right;
}
return null;
}
public void Remove(int target)
{
// if the tree is empty:
if (m_top == null)
return;
if (m_top.Data == target)
{
RemoveRootNode(target);
}
else
{
RemoveNonrootNode(target);
}
}
private void RemoveNonrootNode(int target)
{
BSTNode cur = m_top;
BSTNode parent = null;
//First, find the target node that we need to remove
// we'll have the 'parent' reference trail the cur pointer down the tree
// so when we stop, cur is the node to remove, and parent is one above it.
while (cur!= null && cur.Data != target)
{
parent = cur;
if (target > cur.Data)
cur = cur.Right;
else
cur = cur.Left;
}
// Next, we figure out which of the cases we're in
// Case 1: The target node has no children
if (cur.Left == null && cur.Right == null)
{
if (parent.Left==cur)
parent.Left = null;
else
parent.Right = null;
}
// Case 2: The target node has 1 child
// (You may want to split out the left vs. right child thing)
else if (cur.Left == null)
{
BSTNode cur2 = cur;
cur = cur.Right;
cur2 = null;
return;
}
else if (cur.Right == null)
{
BSTNode cur2 = cur;
cur = cur.Right;
cur2 = null;
return;
}
// Case 3: The target node has 2 children
BSTNode removee = FindAndRemoveNextSmallerValue(target, cur);
cur.Data = removee.Data;
return;
}
private void RemoveRootNode(int target)
{
// If we're here, it's because we're removing the top-most node (the 'root' node)
// Case 1: Root has no children
if (m_top.Left == null && m_top.Right == null)
{
m_top = null; // Therefore, the tree is now empty
return;
}
// Case 2: Root has 1 child
else if (m_top.Left == null)
{
// 1 (right) child, OR zero children (right may also be null)
m_top = m_top.Right; // Right is null or another node - either way is correct
return;
}
else if (m_top.Right == null)
{
// If we're here, Left is not null, so there MUST be one (Left) Child
m_top = m_top.Left;
return;
}
// Case 3: Root has two children - this is where it gets interesting :)
else
{
// 2 children - find (and remove) next smaller value
// use that data to overwrite the current data.
BSTNode removee = FindAndRemoveNextSmallerValue(target, m_top);
m_top.Data = removee.Data;
return;
}
}
/// <summary>
/// This method takes 1 step to the left, then walks as far to the right
/// as possible. Once that right-most node is found, it's removed & returned.
/// Note that the node MAY be immediately to the left of the <B>startHere</B>
/// parameter, if startHere.Left.Right == null
/// </summary>
/// <param name="smallerThanThis"></param>
/// <param name="startHere"></param>
/// <returns></returns>
private BSTNode FindAndRemoveNextSmallerValue(int smallerThanThis, BSTNode startHere)
{
BSTNode parent = startHere;
BSTNode child = startHere.Left;
if (child.Data == smallerThanThis)
{
child = null;
}
while (child.Right != null)
{
parent = child;
child = child.Right;
}
parent = child;
child = null;
return parent;
}
// Given the value of a node, find (and remove) the predessor node in the tree
// returns the value of the predecessor node, or Int32.MinValue if no such value was found
public int TestFindAndRemoveNextSmallest(int sourceNode)
{
BSTNode startAt = this.FindNode(sourceNode);
// sourceNode should == startAt.Data, unless startAt is null)
BSTNode removed = FindAndRemoveNextSmallerValue(sourceNode, startAt);
if (removed != null)
return removed.Data;
else
return Int32.MinValue;
}
}
At first sight, there seems to be this bug:
else if (cur.Left == null)
{
BSTNode cur2 = cur;
cur = cur.Right;
cur2 = null;
return;
}
else if (cur.Right == null)
{
BSTNode cur2 = cur;
// cur = cur.Right; // THIS SHOULD BE .Left, because .Right is NULL
cur = cur.Left; // THIS IS THE FIX
cur2 = null;
return;
}
But your actual problem is; updating the cur reference to something else does not change the pointer to the same object (cur) held by its parent. Actually, you did it right in Case 1, but somehow missed it in Case 2. Therefore; the full fix is: (only fixing the failing test. Promising no more).
// Case 2: The target node has 1 child
// (You may want to split out the left vs. right child thing)
else if (cur.Left == null)
{
if (parent.Left == cur)
{
parent.Left = cur.Right;
}
else
{
parent.Right = cur.Right;
}
return;
}
else if (cur.Right == null)
{
if(parent.Left == cur)
{
parent.Left = cur.Left;
}
else
{
parent.Right = cur.Left;
}
return;
}

Why is my if statement in my contains method unreachable? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 4 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
When I run my program my 'if' statement is compiled as unreachable code which in turn, causes my contains method to continuously print false even though the number exists within the tree. I can't figure out why could any one help me please? I'm fairly new to programming.
Here is my node class.
class Node<T> where T : IComparable
{
private T data;
private int balanceFactor = 0; //added for AVLTree
public Node<T> Left, Right;
public Node(T item)
{
data = item;
Left = null;
Right = null;
}
public T Data
{
set { data = value; }
get { return data; }
}
}
Here is my binary search tree class.
class BSTree<T> : BinTree<T> where T : IComparable
{ //root declared as protected in Parent Class – Binary Tree
public BSTree()
{
root = null;
}
public void InsertItem(T item)
{
insertItem(item, ref root);
}
private void insertItem(T item, ref Node<T> tree)
{
if (tree == null)
tree = new Node<T>(item);
else if (item.CompareTo(tree.Data) < 0)
insertItem(item, ref tree.Left);
else if (item.CompareTo(tree.Data) > 0)
insertItem(item, ref tree.Right);
}
public int Height()
//Return the max level of the tree
{
return Height(root);
}
protected int Height(Node<T> current)
{
if (current == null) return 0;
return 1 + Math.Max(Height(current.Left), Height(current.Right));
}
public int Count()
//Return the number of nodes in the tree
{
return Height(root);
}
public int Count(ref Node<T> current)
//Return the number of nodes in the tree
{
int counter = 0;
if (current == null)
{
return 0;
}
else if (current.Left != null)
{
counter += Count(ref current.Left);
counter++;
}
if (current.Right != null)
{
counter += Count(ref current.Right);
counter++;
}
return counter;
}
public Boolean Contains(T item)
//Return true if the item is contained in the BSTree, false //otherwise.
{
Node<T> current = root;
if (current.Data.CompareTo(item) == 0)
{
{
return true;
}
if (current.Data.CompareTo(item) > 0)
{
current = current.Left;
}
if (current.Data.CompareTo(item) < 0)
{
current = current.Right;
}
}
return false;
}
private T leastItem(Node<T> tree)
{
if (tree.Left == null)
return tree.Data;
else
return leastItem(tree.Left);
}
}
Lastly my main class.
class Program
{
static void Main(string[] args)
{
BSTree<int> treeBranch = new BSTree<int>();
treeBranch.InsertItem(77);
treeBranch.InsertItem(20);
treeBranch.InsertItem(37);
treeBranch.InsertItem(15);
treeBranch.InsertItem(22);
treeBranch.InsertItem(30);
Console.WriteLine(treeBranch.Count());
Console.WriteLine(treeBranch.Height());
Console.WriteLine(treeBranch.Contains(15));
string InOrder = "in order :";
treeBranch.InOrder(ref InOrder);
Console.WriteLine(InOrder);
Console.WriteLine("\n");
Console.ReadKey();
}
}
if (current.Data.CompareTo(item) == 0)
{
{ <==== here
return true;
}
if (current.Data.CompareTo(item) > 0)
{
current = current.Left;
}
if (current.Data.CompareTo(item) < 0)
{
current = current.Right;
}
}
There's no condition to return true;. Change your code to this:
if (current.Data.CompareTo(item) == 0)
{
return true;
}
else if (current.Data.CompareTo(item) > 0)
{
current = current.Left;
}
else if (current.Data.CompareTo(item) < 0)
{
current = current.Right;
}
To many { and } in this code
if (current.Data.CompareTo(item) == 0)
{
{
return true;
}

What is the best alternative for a concurrent task queue, not using .net 4.0

I'm trying to implement a framework for working with multiple cores in Unity applications.
What I have so far is a non-blocking queue implemented by Julian M Bucknal. It seems to work very well for my purposes. I've created a task class, and a result class, and use two queues to distribute and collect the work which is processed on the secondary threads.
The remaining issue is that since this code is going to be used a lot in performance critical sections of my application, I would really like to minimize the use of the garbage collector.
Is there a known library / template / technique that could help me make this improvement?
using System.Threading;
public class LockFreeQueue<T> {
internal struct SingleLinkNode<U> where U : T {
// Note; the Next member cannot be a property since
// it participates in many CAS operations
public SingleLinkNode<U> Next;
public U Item;
}
static private bool CAS<V>(ref V location, V comparand, V newValue) where V : class {
return
(object) comparand ==
(object) Interlocked.CompareExchange<V>(ref location, newValue, comparand);
}
SingleLinkNode<T> head;
SingleLinkNode<T> tail;
public LockFreeQueue() {
head = new SingleLinkNode<T>();
tail = head;
}
public void Enqueue(T item) {
SingleLinkNode<T> oldTail = null;
SingleLinkNode<T> oldTailNext;
SingleLinkNode<T> newNode = new SingleLinkNode<T>();
newNode.Item = item;
bool newNodeWasAdded = false;
while (!newNodeWasAdded) {
oldTail = tail;
oldTailNext = oldTail.Next;
if (tail == oldTail) {
if (oldTailNext == null)
newNodeWasAdded = CAS<SingleLinkNode<T>>(ref tail.Next, null, newNode);
else
CAS<SingleLinkNode<T>>(ref tail, oldTail, oldTailNext);
}
}
CAS<SingleLinkNode<T>>(ref tail, oldTail, newNode);
}
public bool Dequeue(out T item) {
item = default(T);
SingleLinkNode<T> oldHead = null;
bool haveAdvancedHead = false;
while (!haveAdvancedHead) {
oldHead = head;
SingleLinkNode<T> oldTail = tail;
SingleLinkNode<T> oldHeadNext = oldHead.Next;
if (oldHead == head) {
if (oldHead == oldTail) {
if (oldHeadNext == null) {
return false;
}
CAS<SingleLinkNode<T>>(ref tail, oldTail, oldHeadNext);
} else {
item = oldHeadNext.Item;
haveAdvancedHead = CAS<SingleLinkNode<T>>(ref head, oldHead, oldHeadNext);
}
}
}
return true;
}
public T Dequeue() {
T result;
Dequeue(out result);
return result;
}
}
I managed to minimize the garbage collection by reusing instances of SingleLinkNode<T>.
Here's my customized non-blocking stack:
using System.Threading;
public class LockFreeLinkPool<T> {
private SingleLinkNode<T> head;
public LockFreeLinkPool() {
head = new SingleLinkNode<T>();
}
public void Push(SingleLinkNode<T> newNode) {
newNode.Item = default(T);
do {
newNode.Next = head.Next;
} while (!SyncMethods.CAS<SingleLinkNode<T>>(ref head.Next, newNode.Next, newNode));
return;
}
public bool Pop(out SingleLinkNode<T> node) {
do {
node = head.Next;
if (node == null) {
return false;
}
} while (!SyncMethods.CAS<SingleLinkNode<T>>(ref head.Next, node, node.Next));
return true;
}
}
I carefully clean all the instances SingleLinkNode before and after storage. This has some very cool implications for our usage of threads in Unity.

"Sorting" a Tree Data Structure

I made a Tree Data Structure and I want the Elements to sort like this:
10
/ \
5 12
/ \ / \
3 7 11 18
If the value of the added element is smaller than the value of the other element, it should be linked left, and if bigger, right. My problem is, that I just can't get the sorting method right.
class Tree
{
private class TElement
{
public int _value;
public TElement _left;
public TElement _right;
public TElement(int value)
{
_value = value;
}
}
private TElement RootElement;
public void Add(int value)
{
TElement newElement = new TElement(value);
TElement current = new TElement(value);
current = RootElement;
if (RootElement == null)
{
RootElement = newElement;
return;
}
SortNewElement(RootElement, RootElement, newElement, RootElement);
}
private void SortNewElement(TElement left, TElement right, TElement newElement, TElement RootElement)
{
if (newElement._value < RootElement._value && RootElement._left == null)
{
left._left = newElement;
return;
}
if (newElement._value > RootElement._value && RootElement._right == null)
{
right._right = newElement;
return;
}
if (newElement._value < left._value && left._left == null)
{
left._left = newElement;
return;
}
if (newElement._value > right._value && right._right == null)
{
right._right = newElement;
return;
}
SortNewElement(left._left, right._right, newElement, RootElement);
}
}
I know it doesn't work because it's trying to get the linked nodes of a null element.
From what i can understand from your question you are just trying to insert a new node in a binary search tree. Its inorder traversal will be a sorted array.
You can do so by the following simple pseudo code
insert_new( Node* node, value)
{
if(value > node->value)
{
if(node->right != null)
{
insert_new(node->right,value);
}
else
{
node->right = new Node(value);
return;
}
}
else
{
if(node->left != null)
{
insert_new(node->left,value)
}
else
{
node->left = new Node(value);
return;
}
}
}
class element{
public:
int value;
*element left;
*element right;
element(int value)
value = value;
public add(&element a)
if (a != null)
{
if (left!=null){
left = a;
}
else{
if (left.value > a.value){
right = left;
left= a;
}
else{
right=a;
}
}

Object reference not set to an instance of an object- Linked List Example

I am seeing following errors :
Object reference not set to an instance of an object!
Check to determinate if the object is null before calling the method!
I made a small test program for Sorted Linked Lists.
Here is the code where the error comes!
public void Insert(double data)
{
Link newLink = new Link(data);
Link current = first;
Link previous = null;
if (first == null)
{
first = newLink;
}
else
{
while (data > current.DData && current != null)
{
previous = current;
current = current.Next;
}
previous.Next = newLink;
newLink.Next = current;
}
}
It says that the current referenc is null while (data > current.DData && current != null), but I assigned it: current = first;
The rest is the complete code of the Program!
class Link
{
double dData;
Link next=null;
public Link Next
{
get { return next; }
set { next = value; }
}
public double DData
{
get { return dData; }
set { dData = value; }
}
public Link(double dData)
{
this.dData = dData;
}
public void DisplayLink()
{
Console.WriteLine("Link : "+ dData);
}
}
class SortedList
{
Link first;
public SortedList()
{
first = null;
}
public bool IsEmpty()
{
return (this.first == null);
}
public void Insert(double data)
{
Link newLink = new Link(data);
Link current = first;
Link previous = null;
if (first == null)
{
first = newLink;
}
else
{
while (data > current.DData && current != null)
{
previous = current;
current = current.Next;
}
previous.Next = newLink;
newLink.Next = current;
}
}
public Link Remove()
{
Link temp = first;
first = first.Next;
return temp;
}
public void DisplayList()
{
Link current;
current = first;
Console.WriteLine("Display the List!");
while (current != null)
{
current.DisplayLink();
current = current.Next;
}
}
}
class SortedListApp
{
public void TestSortedList()
{
SortedList newList = new SortedList();
newList.Insert(20);
newList.Insert(22);
newList.Insert(100);
newList.Insert(1000);
newList.Insert(15);
newList.Insert(11);
newList.DisplayList();
newList.Remove();
newList.DisplayList();
}
}
You are perhaps assuming that the while loop is breaking on the first iteration which it's not it's the assignment in the while loop that eventually breaks it.
Eventually current is NULL based on your code, you even test for it - change it to this and it should be fine:
while (current != null && data > current.DData)
{
previous = current;
current = current.Next;
}
Agree that you have done
current = first;
but then the beginning of your class first is null
class SortedList
{
Link first;
please assign something to first else it will be null

Categories