Can't delete Node from a BST - C# - c#

I am learning data structures, lately I've been trying to create a BST. Here is the code for that:
class Program
{
static void Main(string[] args)
{
BST tree = new BST();
tree.Insert(3);
tree.Insert(6);
tree.Insert(12);
tree.Insert(2);
tree.Insert(8);
tree.InOrder(tree.root);
// output: 2 3 6 8 12
tree.Delete(12);
tree.InOrder(tree.root);
// output: 2 3 6
}
}
class Node
{
public Node lc;
public int value;
public Node rc;
}
class BST
{
public Node root;
public BST()
{
root = null;
}
public void Insert(int value)
{
Node temp = new Node();
temp.value = value;
if (root == null)
{
root = temp;
}
else
{
Node parent = null;
Node current = root;
while (current != null)
{
parent = current;
if (value <= current.value)
{
current = current.lc;
}
else
{
current = current.rc;
}
}
if (value <= parent.value)
{
parent.lc = temp;
}
else
{
parent.rc = temp;
}
}
}
public void Delete(int value)
{
Node current = root;
Node parent = null;
while (current != null)
{
parent = current;
if (value <= current.value)
{
current = current.lc;
if (current.value == value)
{
parent.lc = null;
break;
}
}
else
{
current = current.rc;
if (value == current.value)
{
parent.rc = null;
break;
}
}
}
}
public void InOrder(Node root)
{
if (root != null)
{
InOrder(root.lc);
Console.WriteLine(root.value);
InOrder(root.rc);
}
}
}
However, I am encountering an issue with deleting the Node identified, as of now I am writing the code for deleting a node which doesn't have any children.
For some reason when I try to delete the Node with which holds the value 12, the Node with the value 8 gets deleted too....I tried to dry run, but still can't understand why I am loosing connection with that other Node which holds 8.

All right, so it turned out as Sasha pointed, I was drawing the tree incorrectly and was loosing the connection to the Node that holds the value of 8 because it was connected to the left of the Node that was deleted.

Related

How do i initialize a binary tree in c#

Can someone please tell me what i need to put in place of the '//code missing here'?
Where i have put "code missing" is where i am stuck. I am not sure what i need to put in place. I am new to binary trees so unfortunately am not very experienced with how they work. For my assignment this is the format my teacher wants so other tutorials online have not been particularly useful
using System;
public class Program
{
public class binarytree
{
public class node
{ // Single element of tree (node)
public string data;
public node //CODE MISSING HERE
public node rightPointer;
}
public node root;
public bool add(string item)
{
try //in case of memory overflow (full)
{
// store new item in memory and start looking from root of tree
node newNode = new node();
newNode.data = item;
newNode.//CODE MISSING HERE
newNode.rightPointer = //CODE MISSING HERE
node currentNode = root;
//Case that tree is empty
if (currentNode == null)
{
root = newNode;
return true;
}
else
{
//work out where to put new item, by traversing tree until we find a left
node previous = currentNode;
while (currentNode != null)
{
previous = currentNode;
//compareTo compares two strings, returns val <0 if lower
if (item.CompareTo(currentNode.data) //CODE MISSING HERE
{
currentNode = //CODE MISSING HERE
}
else
{
currentNode = currentNode.rightPointer;
}
}
if (item.CompareTo(previous.data)<0)
{
//CODE MISSING HERE
}
else
{
previous.rightPointer = newNode;
}
return true;
}
}
catch
{
return false;
}
}
}
public static void Main()
{
binarytree bt = new binarytree();
bt.add("I am root");
bt.add("Avengers");
bt.add("Marvel");
Console.WriteLine(bt.root.data);
Console.WriteLine(bt.root.//CODE MISSING HERE
Console.WriteLine(bt.root.rightPointer.data);
}
}
I have sorted it
using System;
public class Program
{
public class binarytree
{
public class node
{ // Single element of tree (node)
public string data;
public node leftPointer;
public node rightPointer;
}
public node root;
public bool add(string item)
{
try //in case of memory overflow (full)
{
// store new item in memory and start looking from root of tree
node newNode = new node();
newNode.data = item;
newNode.leftPointer = null;
newNode.rightPointer = null;
node currentNode = root;
//Case that tree is empty
if (currentNode == null)
{
root = newNode;
return true;
}
else
{
//work out where to put new item, by traversing tree until we find a left
node previous = currentNode;
while (currentNode != null)
{
previous = currentNode;
//compareTo compares two strings, returns val <0 if lower
if (item.CompareTo(currentNode.data)<0)
{
currentNode = currentNode.leftPointer;
}
else
{
currentNode = currentNode.rightPointer;
}
}
if (item.CompareTo(previous.data)<0)
{
previous.leftPointer = newNode;
}
else
{
previous.rightPointer = newNode;
}
return true;
}
}
catch
{
return false;
}
}
}
public static void Main()
{
binarytree bt = new binarytree();
bt.add("I am root");
bt.add("Avengers");
bt.add("Marvel");
Console.WriteLine(bt.root.data);
Console.WriteLine(bt.root.leftPointer.data);
Console.WriteLine(bt.root.rightPointer.data);
}
}

Insert function dosen't insert

Ive starting learning C# with a background of c/c++. I am creating a simple BST but my insert function wont work. Any help would greatly be appreciated.
I get this kind of error when not passing by reference in c/c++. Since I created a two classes Node and BST, shouldn't they be passed by reference? Ive worked on this problem for a couple of hours and tried to change my code but with no luck.
public Node(int data)
{
this.data = data;
this.right = null;
this.left = null;
}
public Node Left
{
get { return left; }
set { left = value; }
}
public Node Right
{
get { return right; }
set { right = value; }
}
public int Data
{
get { return data; }
set { data = value; }
}
}
class BST
{
private Node root;
public BST()
{
root = null;
}
public Node Root
{
get { return root; }
set { root = value; }
}
public void Insert(int data)
{
if (root == null)
{
root = new Node(data);
}
else
{
InsertHelper(root, data);
}
}
public void InsertHelper( Node root, int data)
{
if (root == null)
{
root = new Node(data);
//return root;
}
if (root.Data > data)
{
InsertHelper(root.Left, data);
}
if (root.Data < data)
{
InsertHelper(root.Right, data);
}
}
You are assigning a new node to the argument pointer instead of original one. Insert should be:
public void Insert(int data)
{
if (root == null)
{
root = new Node(data);
}
else
{
root = InsertHelper(root, data);
}
}
and InsertHelper should be:
public Node InsertHelper( Node root, int data)
{
if (root == null)
return new Node(data);
if (root.Data > data)
{
root.Left = InsertHelper(root.Left, data);
}
if (root.Data < data)
{
root.Right = InsertHelper(root.Right, data);
}
return root;
}
In fact you don't even need Insert since InsertHelper already deals with root being null
Main method for testing:
public static void Main()
{
BST bst = new BST();
bst.Insert(5);
bst.Insert(6);
bst.Insert(4);
bst.Insert(7);
bst.Insert(3);
Console.WriteLine(bst.Root.Data + " ");
Console.WriteLine(bst.Root.Left.Data + " ");
Console.WriteLine(bst.Root.Right.Data + " ");
Console.WriteLine(bst.Root.Left.Left.Data + " ");
Console.WriteLine(bst.Root.Right.Right.Data + " ");
}

Binary search tree remove with reference to parents

First off, this is a school assignment, so there. I wouldn't be posting if it weren't for the fact that I'm really hurting for help.
Now we have this binary search tree we are supposed to implement. Basically, this class below is complete, I am given to understand.
public class BinarySearchTree<T> where T : IComparable<T>
{
BinarySearchTreeNode<T> _root;
public BinarySearchTreeNode<T> Root
{
get { return _root; }
}
public BinarySearchTree()
{
}
public BinarySearchTree(BinarySearchTreeNode<T> root)
{
_root = root;
}
public void Insert(T value)
{
if (_root != null)
_root.Insert(value);
else
_root = new BinarySearchTreeNode<T>(value);
}
public void Remove(T value)
{
if (_root == null)
return;
if (_root.LeftChild != null || _root.RightChild != null)
{
_root.Remove(value);
}
else if (_root.Value.CompareTo(value) == 0)
{
_root = null;
}
}
public bool Find(T value)
{
if (_root != null)
return _root.Find(value);
else
return false;
}
}
And here the class I am supposed to implement, or at least as far as I have gotten.
public class BinarySearchTreeNode<T> where T : IComparable<T>
{
private T _value;
public T Value
{
get { return _value; }
}
public BinarySearchTreeNode<T> LeftChild
{
get { return _leftChild; }
set { _leftChild = value; }
}
private BinarySearchTreeNode<T> _leftChild, _parent, _rightChild;
public BinarySearchTreeNode<T> RightChild
{
get { return _rightChild; }
set { _rightChild = value; }
}
public BinarySearchTreeNode<T> Parent
{
get { return _parent; }
set { _parent = value; }
}
public BinarySearchTreeNode(T value)
{
_value = value;
Parent = this;
}
public void Insert(T value)
{
if (value.CompareTo(Parent.Value) < 0)
{
if (LeftChild != null)
{
LeftChild.Insert(value);
}
else
{
LeftChild = new BinarySearchTreeNode<T>(value);
LeftChild.Parent = this;
}
}
else if (Value.CompareTo(Parent.Value) >= 0)
{
if (RightChild != null)
RightChild.Insert(value);
else{
RightChild = new BinarySearchTreeNode<T>(value);
Righthild.Parent = this;
}
}
}
public void Remove(T value)
{
if (LeftChild != null)
if (value.CompareTo(Parent.Value) < 0)
LeftChild.Remove(value);
else if (RightChild != null)
if (value.CompareTo(Parent.Value) >= 0)
RightChild.Remove(value);
}
public bool Find(T value)
{
if (value.Equals(Parent.Value))
return true;
else if (value.CompareTo(Parent.Value) < 0)
{
if (LeftChild != null)
return LeftChild.Find(value);
}
else if (value.CompareTo(Parent.Value) > 0)
{
if (RightChild != null)
return RightChild.Find(value);
}
return false;
}
}
The issue is that I can't quite seem to get my head around just how I am supposed to properly implement remove, so that I can remove a node simply by pointing towards the parents, for instance. Any help or hints is appreciated.
Edit(!)
So I got almost everything in order, baring one thing which is case 2 for the remove method.
//Case 2: If node has only one child, copy the value of the child to your node, and assign LeftChild or RightChild to null (as is the case)
if (RightChild != null && LeftChild == null)
{
if (value.CompareTo(this.Parent._value) > 0)
{
Parent.RightChild = RightChild;
RightChild = null;
}
}
if (RightChild == null && LeftChild != null)
{
if (value.CompareTo(Parent._value) < 0)
{
Parent.LeftChild = LeftChild;
LeftChild = null;
}
}
Basically, I am completely unable to replace the original node. If I have have
4 - 3 - 2 ( preorder ) and I want to remove 3 then I can do that and get 4 - 2.
However, if I want to remove 4 , it won't do anything, though it only got one child. I am think thats because it doesn't have a parent, but I am unsure of how to get around that. Any ideas?
Binary Search Tree
There are three possible cases to consider:
Deleting a leaf (node with no children): Deleting a leaf is easy, as we can simply remove it from the tree.
Deleting a node with one child: Remove the node and replace it with its child.
Deleting a node with two children: Call the node to be deleted N. Do not delete N. Instead, choose either its in-order successor node or its in-order predecessor node, R. Replace the value of N with the value of R, then delete R.
Add one more condition to your remove method whose pseudo-code is:
if (value.CompareTo(Parent.Value) == 0){
//Case 1: If node has no children, then make Parent = null
// Case 2: If node has only one child, copy the value of the child to your node, and assign LeftChild or RightChild to null (as is the case)
//Case 3: Find the in-order successor, copy its value to the current node and delete the in-order successor.
}

Creating a very simple linked list

I am trying to create a linked list just to see if I can, and I am having trouble getting my head around it. Does anyone have an example of a very simple implementation of Linked list using C#? All the examples I have found so far are quite overdone.
A Linked List, at its core is a bunch of Nodes linked together.
So, you need to start with a simple Node class:
public class Node {
public Node next;
public Object data;
}
Then your linked list will have as a member one node representing the head (start) of the list:
public class LinkedList {
private Node head;
}
Then you need to add functionality to the list by adding methods. They usually involve some sort of traversal along all of the nodes.
public void printAllNodes() {
Node current = head;
while (current != null)
{
Console.WriteLine(current.data);
current = current.next;
}
}
Also, inserting new data is another common operation:
public void Add(Object data) {
Node toAdd = new Node();
toAdd.data = data;
Node current = head;
// traverse all nodes (see the print all nodes method for an example)
current.next = toAdd;
}
This should provide a good starting point.
Based on what #jjnguy said, here's the full Console App example:
public class Node
{
public Node next;
public Object data;
}
public class LinkedList
{
private Node head;
public void printAllNodes()
{
Node current = head;
while (current != null)
{
Console.WriteLine(current.data);
current = current.next;
}
}
public void AddFirst(Object data)
{
Node toAdd = new Node();
toAdd.data = data;
toAdd.next = head;
head = toAdd;
}
public void AddLast(Object data)
{
if (head == null)
{
head = new Node();
head.data = data;
head.next = null;
}
else
{
Node toAdd = new Node();
toAdd.data = data;
Node current = head;
while (current.next != null)
{
current = current.next;
}
current.next = toAdd;
}
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Add First:");
LinkedList myList1 = new LinkedList();
myList1.AddFirst("Hello");
myList1.AddFirst("Magical");
myList1.AddFirst("World");
myList1.printAllNodes();
Console.WriteLine();
Console.WriteLine("Add Last:");
LinkedList myList2 = new LinkedList();
myList2.AddLast("Hello");
myList2.AddLast("Magical");
myList2.AddLast("World");
myList2.printAllNodes();
Console.ReadLine();
}
}
This one is nice:
namespace ConsoleApplication1
{
// T is the type of data stored in a particular instance of GenericList.
public class GenericList<T>
{
private class Node
{
// Each node has a reference to the next node in the list.
public Node Next;
// Each node holds a value of type T.
public T Data;
}
// The list is initially empty.
private Node head = null;
// Add a node at the beginning of the list with t as its data value.
public void AddNode(T t)
{
Node newNode = new Node();
newNode.Next = head;
newNode.Data = t;
head = newNode;
}
// The following method returns the data value stored in the last node in
// the list. If the list is empty, the default value for type T is
// returned.
public T GetFirstAdded()
{
// The value of temp is returned as the value of the method.
// The following declaration initializes temp to the appropriate
// default value for type T. The default value is returned if the
// list is empty.
T temp = default(T);
Node current = head;
while (current != null)
{
temp = current.Data;
current = current.Next;
}
return temp;
}
}
}
Test code:
static void Main(string[] args)
{
// Test with a non-empty list of integers.
GenericList<int> gll = new GenericList<int>();
gll.AddNode(5);
gll.AddNode(4);
gll.AddNode(3);
int intVal = gll.GetFirstAdded();
// The following line displays 5.
System.Console.WriteLine(intVal);
}
I encountered it on msdn here
Here is one with IEnumerable and a Recursive Reverse method though it is no faster than the while loop in the Reverse method both are O(n):
public class LinkedList<T> : IEnumerable
{
private Node<T> _head = null;
public Node<T> Add(T value)
{
var node = new Node<T> {Value = value};
if (_head == null)
{
_head = node;
}
else
{
var current = _head;
while (current.Next != null)
{
current = current.Next;
}
current.Next = node; //new head
}
return node;
}
public T Remove(Node<T> node)
{
if (_head == null)
return node.Value;
if (_head == node)
{
_head = _head.Next;
node.Next = null;
return node.Value;
}
var current = _head;
while (current.Next != null)
{
if (current.Next == node)
{
current.Next = node.Next;
return node.Value;
}
current = current.Next;
}
return node.Value;
}
public void Reverse()
{
Node<T> prev = null;
var current = _head;
if (current == null)
return;
while (current != null)
{
var next = current.Next;
current.Next = prev;
prev = current;
current = next;
}
_head = prev;
}
public void ReverseRecursive()
{
reverseRecursive(_head, null);
}
private void reverseRecursive(Node<T> current, Node<T> prev)
{
if (current.Next == null)
{
_head = current;
_head.Next = prev;
return;
}
var next = current.Next;
current.Next = prev;
reverseRecursive(next, current);
}
public IEnumerator<T> Enumerator()
{
var current = _head;
while (current != null)
{
yield return current.Value;
current = current.Next;
}
}
public IEnumerator GetEnumerator()
{
return Enumerator();
}
}
public class Node<T>
{
public T Value { get; set; }
public Node<T> Next { get; set; }
}
I am a beginner and this helped me:
class List
{
private Element Root;
}
First you create the class List which will contain all the methods.
Then you create the Node-Class, I will call it Element
class Element
{
public int Value;
public Element Next;
}
Then you can start adding methods to your List class. Here is a 'add' method for example.
public void Add(int value)
{
Element newElement = new Element();
newElement.Value = value;
Element rootCopy = Root;
Root = newElement;
newElement.Next = rootCopy;
Console.WriteLine(newElement.Value);
}
public class Node
{
private Object data;
public Node next {get;set;}
public Node(Object data)
{
this.data = data;
}
}
public class Linkedlist
{
Node head;
public void Add(Node n)
{
n.Next = this.Head;
this.Head = n;
}
}
using:
LinkedList sample = new LinkedList();
sample.add(new Node("first"));
sample.Add(new Node("second"))
I am giving an extract from the book "C# 6.0 in a Nutshell by Joseph Albahari and Ben Albahari"
Here’s a demonstration on the use of LinkedList:
var tune = new LinkedList<string>();
tune.AddFirst ("do"); // do
tune.AddLast ("so"); // do - so
tune.AddAfter (tune.First, "re"); // do - re- so
tune.AddAfter (tune.First.Next, "mi"); // do - re - mi- so
tune.AddBefore (tune.Last, "fa"); // do - re - mi - fa- so
tune.RemoveFirst(); // re - mi - fa - so
tune.RemoveLast(); // re - mi - fa
LinkedListNode<string> miNode = tune.Find ("mi");
tune.Remove (miNode); // re - fa
tune.AddFirst (miNode); // mi- re - fa
foreach (string s in tune) Console.WriteLine (s);
Here is a good implementation.
It is short, but implemented Add(x), Delete(x), Contain(x) and Print().
It avoid special process when add to empty list or delete the first element.
While most of other examples did special process when delete the first element.
The list can contain any data type.
using System;
class Node<Type> : LinkedList<Type>
{ // Why inherit from LinkedList? A: We need to use polymorphism.
public Type value;
public Node(Type value) { this.value = value; }
}
class LinkedList<Type>
{
Node<Type> next; // This member is treated as head in class LinkedList, but treated as next element in class Node.
/// <summary> if x is in list, return previos pointer of x. (We can see any class variable as a pointer.)
/// if not found, return the tail of the list. </summary>
protected LinkedList<Type> Previos(Type x)
{
LinkedList<Type> p = this; // point to head
for (; p.next != null; p = p.next)
if (p.next.value.Equals(x))
return p; // find x, return the previos pointer.
return p; // not found, p is the tail.
}
/// <summary> return value: true = success ; false = x not exist </summary>
public bool Contain(Type x) { return Previos(x).next != null ? true : false; }
/// <summary> return value: true = success ; false = fail to add. Because x already exist.
/// </summary> // why return value? If caller want to know the result, they don't need to call Contain(x) before, the action waste time.
public bool Add(Type x)
{
LinkedList<Type> p = Previos(x);
if (p.next != null) // Find x already in list
return false;
p.next = new Node<Type>(x);
return true;
}
/// <summary> return value: true = success ; false = x not exist </summary>
public bool Delete(Type x)
{
LinkedList<Type> p = Previos(x);
if (p.next == null)
return false;
//Node<Type> node = p.next;
p.next = p.next.next;
//node.Dispose(); // GC dispose automatically.
return true;
}
public void Print()
{
Console.Write("List: ");
for (Node<Type> node = next; node != null; node = node.next)
Console.Write(node.value.ToString() + " ");
Console.WriteLine();
}
}
class Test
{
static void Main()
{
LinkedList<int> LL = new LinkedList<int>();
if (!LL.Contain(0)) // Empty list
Console.WriteLine("0 is not exist.");
LL.Print();
LL.Add(0); // Add to empty list
LL.Add(1); LL.Add(2); // attach to tail
LL.Add(2); // duplicate add, 2 is tail.
if (LL.Contain(0))// Find existed element which is head
Console.WriteLine("0 is exist.");
LL.Print();
LL.Delete(0); // Delete head
LL.Delete(2); // Delete tail
if (!LL.Delete(0)) // Delete non-exist element
Console.WriteLine("0 is not exist.");
LL.Print();
Console.ReadLine();
}
}
By the way, the implementation in
http://www.functionx.com/csharp1/examples/linkedlist.htm
have some problem:
Delete() will fail when there is only 1 element.
(Throw exception at line "Head.Next = Current.Next;" because Current is null.)
Delete(position) will fail when deleting first element,
In other words, call Delete(0) will fail.
Dmytro did a good job, but here is a more concise version.
class Program
{
static void Main(string[] args)
{
LinkedList linkedList = new LinkedList(1);
linkedList.Add(2);
linkedList.Add(3);
linkedList.Add(4);
linkedList.AddFirst(0);
linkedList.Print();
}
}
public class Node
{
public Node(Node next, Object value)
{
this.next = next;
this.value = value;
}
public Node next;
public Object value;
}
public class LinkedList
{
public Node head;
public LinkedList(Object initial)
{
head = new Node(null, initial);
}
public void AddFirst(Object value)
{
head = new Node(head, value);
}
public void Add(Object value)
{
Node current = head;
while (current.next != null)
{
current = current.next;
}
current.next = new Node(null, value);
}
public void Print()
{
Node current = head;
while (current != null)
{
Console.WriteLine(current.value);
current = current.next;
}
}
}
public class DynamicLinkedList
{
private class Node
{
private object element;
private Node next;
public object Element
{
get { return this.element; }
set { this.element = value; }
}
public Node Next
{
get { return this.next; }
set { this.next = value; }
}
public Node(object element, Node prevNode)
{
this.element = element;
prevNode.next = this;
}
public Node(object element)
{
this.element = element;
next = null;
}
}
private Node head;
private Node tail;
private int count;
public DynamicLinkedList()
{
this.head = null;
this.tail = null;
this.count = 0;
}
public void AddAtLastPosition(object element)
{
if (head == null)
{
head = new Node(element);
tail = head;
}
else
{
Node newNode = new Node(element, tail);
tail = newNode;
}
count++;
}
public object GetLastElement()
{
object lastElement = null;
Node currentNode = head;
while (currentNode != null)
{
lastElement = currentNode.Element;
currentNode = currentNode.Next;
}
return lastElement;
}
}
Testing with:
static void Main(string[] args)
{
DynamicLinkedList list = new DynamicLinkedList();
list.AddAtLastPosition(1);
list.AddAtLastPosition(2);
list.AddAtLastPosition(3);
list.AddAtLastPosition(4);
list.AddAtLastPosition(5);
object lastElement = list.GetLastElement();
Console.WriteLine(lastElement);
}
public class Node<T>
{
public T item;
public Node<T> next;
public Node()
{
this.next = null;
}
}
class LinkList<T>
{
public Node<T> head { get; set; }
public LinkList()
{
this.head = null;
}
public void AddAtHead(T item)
{
Node<T> newNode = new Node<T>();
newNode.item = item;
if (this.head == null)
{
this.head = newNode;
}
else
{
newNode.next = head;
this.head = newNode;
}
}
public void AddAtTail(T item)
{
Node<T> newNode = new Node<T>();
newNode.item = item;
if (this.head == null)
{
this.head = newNode;
}
else
{
Node<T> temp = this.head;
while (temp.next != null)
{
temp = temp.next;
}
temp.next = newNode;
}
}
public void DeleteNode(T item)
{
if (this.head.item.Equals(item))
{
head = head.next;
}
else
{
Node<T> temp = head;
Node<T> tempPre = head;
bool matched = false;
while (!(matched = temp.item.Equals(item)) && temp.next != null)
{
tempPre = temp;
temp = temp.next;
}
if (matched)
{
tempPre.next = temp.next;
}
else
{
Console.WriteLine("Value not found!");
}
}
}
public bool searchNode(T item)
{
Node<T> temp = this.head;
bool matched = false;
while (!(matched = temp.item.Equals(item)) && temp.next != null)
{
temp = temp.next;
}
return matched;
}
public void DisplayList()
{
Console.WriteLine("Displaying List!");
Node<T> temp = this.head;
while (temp != null)
{
Console.WriteLine(temp.item);
temp = temp.next;
}
}
}
Add a Node class.
Then add a LinkedList class to implement the linked list
Add a test class to execute the linked list
namespace LinkedListProject
{
public class Node
{
public Node next;
public object data;
}
public class MyLinkedList
{
Node head;
public Node AddNodes(Object data)
{
Node node = new Node();
if (node.next == null)
{
node.data = data;
node.next = head;
head = node;
}
else
{
while (node.next != null)
node = node.next;
node.data = data;
node.next = null;
}
return node;
}
public void printnodes()
{
Node current = head;
while (current.next != null)
{
Console.WriteLine(current.data);
current = current.next;
}
Console.WriteLine(current.data);
}
}
[TestClass]
public class LinkedListExample
{
MyLinkedList linkedlist = new MyLinkedList();
[TestMethod]
public void linkedlisttest()
{
linkedlist.AddNodes("hello");
linkedlist.AddNodes("world");
linkedlist.AddNodes("now");
linkedlist.printnodes();
}
}
}
simple c# program to implement Single Link List with operations AddItemStart, AddItemEnd, RemoveItemStart, RemoveItemEnd and DisplayAllItems
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SingleLinkedList
{
class Program
{
Node head;
Node current;
int counter = 0;
public Program()
{
head = new Node();
current = head;
}
public void AddStart(object data)
{
Node newnode = new Node();
newnode.next = head.next;
newnode.data = data;
head.next = newnode;
counter++;
}
public void AddEnd(object data)
{
Node newnode = new Node();
newnode.data = data;
current.next = newnode;
current = newnode;
counter++;
}
public void RemoveStart()
{
if (counter > 0)
{
head.next = head.next.next;
counter--;
}
else
{
Console.WriteLine("No element exist in this linked list.");
}
}
public void RemoveEnd()
{
if (counter > 0)
{
Node prevNode = new Node();
Node cur = head;
while (cur.next != null)
{
prevNode = cur;
cur = cur.next;
}
prevNode.next = null;
}
else
{
Console.WriteLine("No element exist in this linked list.");
}
}
public void Display()
{
Console.Write("Head ->");
Node curr = head;
while (curr.next != null)
{
curr = curr.next;
Console.WriteLine(curr.data.ToString());
}
}
public class Node
{
public object data;
public Node next;
}
static void Main(string[] args)
{
Program p = new Program();
p.AddEnd(2);
p.AddStart(1);
p.AddStart(0);
p.AddEnd(3);
p.Display();
p.RemoveStart();
Console.WriteLine("Removed node from Start");
p.Display();
Console.WriteLine("Removed node from End");
p.RemoveEnd();
p.Display();
Console.ReadKey();
}
}
}
The selected answer doesn't have an iterator; it is more basic, but perhaps not as useful.
Here is one with an iterator/enumerator. My implementation is based on Sedgewick's bag; see http://algs4.cs.princeton.edu/13stacks/Bag.java.html
void Main()
{
var b = new Bag<string>();
b.Add("bike");
b.Add("erasmus");
b.Add("kumquat");
b.Add("beaver");
b.Add("racecar");
b.Add("barnacle");
foreach (var thing in b)
{
Console.WriteLine(thing);
}
}
// Define other methods and classes here
public class Bag<T> : IEnumerable<T>
{
public Node<T> first;// first node in list
public class Node<T>
{
public T item;
public Node<T> next;
public Node(T item)
{
this.item = item;
}
}
public void Add(T item)
{
Node<T> oldFirst = first;
first = new Node<T>(item);
first.next = oldFirst;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<T> GetEnumerator()
{
return new BagEnumerator<T>(this);
}
public class BagEnumerator<V> : IEnumerator<T>
{
private Node<T> _head;
private Bag<T> _bag;
private Node<T> _curNode;
public BagEnumerator(Bag<T> bag)
{
_bag = bag;
_head = bag.first;
_curNode = default(Node<T>);
}
public T Current
{
get { return _curNode.item; }
}
object IEnumerator.Current
{
get { return Current; }
}
public bool MoveNext()
{
if (_curNode == null)
{
_curNode = _head;
if (_curNode == null)
return false;
return true;
}
if (_curNode.next == null)
return false;
else
{
_curNode = _curNode.next;
return true;
}
}
public void Reset()
{
_curNode = default(Node<T>); ;
}
public void Dispose()
{
}
}
}
I've created the following LinkedList code with many features. It is available for public under the CodeBase github public repo.
Classes:
Node and LinkedList
Getters and Setters: First and Last
Functions:
AddFirst(data), AddFirst(node), AddLast(data), RemoveLast(), AddAfter(node, data), RemoveBefore(node), Find(node), Remove(foundNode), Print(LinkedList)
using System;
using System.Collections.Generic;
namespace Codebase
{
public class Node
{
public object Data { get; set; }
public Node Next { get; set; }
public Node()
{
}
public Node(object Data, Node Next = null)
{
this.Data = Data;
this.Next = Next;
}
}
public class LinkedList
{
private Node Head;
public Node First
{
get => Head;
set
{
First.Data = value.Data;
First.Next = value.Next;
}
}
public Node Last
{
get
{
Node p = Head;
//Based partially on https://en.wikipedia.org/wiki/Linked_list
while (p.Next != null)
p = p.Next; //traverse the list until p is the last node.The last node always points to NULL.
return p;
}
set
{
Last.Data = value.Data;
Last.Next = value.Next;
}
}
public void AddFirst(Object data, bool verbose = true)
{
Head = new Node(data, Head);
if (verbose) Print();
}
public void AddFirst(Node node, bool verbose = true)
{
node.Next = Head;
Head = node;
if (verbose) Print();
}
public void AddLast(Object data, bool Verbose = true)
{
Last.Next = new Node(data);
if (Verbose) Print();
}
public Node RemoveFirst(bool verbose = true)
{
Node temp = First;
Head = First.Next;
if (verbose) Print();
return temp;
}
public Node RemoveLast(bool verbose = true)
{
Node p = Head;
Node temp = Last;
while (p.Next != temp)
p = p.Next;
p.Next = null;
if (verbose) Print();
return temp;
}
public void AddAfter(Node node, object data, bool verbose = true)
{
Node temp = new Node(data);
temp.Next = node.Next;
node.Next = temp;
if (verbose) Print();
}
public void AddBefore(Node node, object data, bool verbose = true)
{
Node temp = new Node(data);
Node p = Head;
while (p.Next != node) //Finding the node before
{
p = p.Next;
}
temp.Next = p.Next; //same as = node
p.Next = temp;
if (verbose) Print();
}
public Node Find(object data)
{
Node p = Head;
while (p != null)
{
if (p.Data == data)
return p;
p = p.Next;
}
return null;
}
public void Remove(Node node, bool verbose = true)
{
Node p = Head;
while (p.Next != node)
{
p = p.Next;
}
p.Next = node.Next;
if (verbose) Print();
}
public void Print()
{
Node p = Head;
while (p != null) //LinkedList iterator
{
Console.Write(p.Data + " ");
p = p.Next; //traverse the list until p is the last node.The last node always points to NULL.
}
Console.WriteLine();
}
}
}
Using #yogihosting answer when she used the Microsoft built-in LinkedList and LinkedListNode to answer the question, you can achieve the same results:
using System;
using System.Collections.Generic;
using Codebase;
namespace Cmd
{
static class Program
{
static void Main(string[] args)
{
var tune = new LinkedList(); //Using custom code instead of the built-in LinkedList<T>
tune.AddFirst("do"); // do
tune.AddLast("so"); // do - so
tune.AddAfter(tune.First, "re"); // do - re- so
tune.AddAfter(tune.First.Next, "mi"); // do - re - mi- so
tune.AddBefore(tune.Last, "fa"); // do - re - mi - fa- so
tune.RemoveFirst(); // re - mi - fa - so
tune.RemoveLast(); // re - mi - fa
Node miNode = tune.Find("mi"); //Using custom code instead of the built in LinkedListNode
tune.Remove(miNode); // re - fa
tune.AddFirst(miNode); // mi- re - fa
}
}
I have a doubly Linked List which can be used as a stack or a queue. If you look at the code and think about what it does and how it does it I bet you will understand everything about it. I am sorry but somehow I couldn't pate the full code here so I here is the link for the linkedlist(also I got the binary tree in the solution): https://github.com/szabeast/LinkedList_and_BinaryTree
A linked list is a node-based data structure. Each node designed with two portions (Data & Node Reference).Actually, data is always stored in Data portion (Maybe primitive data types eg Int, Float .etc or we can store user-defined data type also eg. Object reference) and similarly Node Reference should also contain the reference to next node, if there is no next node then the chain will end.
This chain will continue up to any node doesn't have a reference point to the next node.
Please find the source code from my tech blog - http://www.algonuts.info/linked-list-program-in-java.html
package info.algonuts;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
class LLNode {
int nodeValue;
LLNode childNode;
public LLNode(int nodeValue) {
this.nodeValue = nodeValue;
this.childNode = null;
}
}
class LLCompute {
private static LLNode temp;
private static LLNode previousNode;
private static LLNode newNode;
private static LLNode headNode;
public static void add(int nodeValue) {
newNode = new LLNode(nodeValue);
temp = headNode;
previousNode = temp;
if(temp != null)
{ compute(); }
else
{ headNode = newNode; } //Set headNode
}
private static void compute() {
if(newNode.nodeValue < temp.nodeValue) { //Sorting - Ascending Order
newNode.childNode = temp;
if(temp == headNode)
{ headNode = newNode; }
else if(previousNode != null)
{ previousNode.childNode = newNode; }
}
else
{
if(temp.childNode == null)
{ temp.childNode = newNode; }
else
{
previousNode = temp;
temp = temp.childNode;
compute();
}
}
}
public static void display() {
temp = headNode;
while(temp != null) {
System.out.print(temp.nodeValue+" ");
temp = temp.childNode;
}
}
}
public class LinkedList {
//Entry Point
public static void main(String[] args) {
//First Set Input Values
List <Integer> firstIntList = new ArrayList <Integer>(Arrays.asList(50,20,59,78,90,3,20,40,98));
Iterator<Integer> ptr = firstIntList.iterator();
while(ptr.hasNext())
{ LLCompute.add(ptr.next()); }
System.out.println("Sort with first Set Values");
LLCompute.display();
System.out.println("\n");
//Second Set Input Values
List <Integer> secondIntList = new ArrayList <Integer>(Arrays.asList(1,5,8,100,91));
ptr = secondIntList.iterator();
while(ptr.hasNext())
{ LLCompute.add(ptr.next()); }
System.out.println("Sort with first & Second Set Values");
LLCompute.display();
System.out.println();
}
}

Is there a .NET data structure with the following characteristics of a Binary Search Tree?

I know that SortedDictionary is a binary search tree (and it can almost do what I need to do!) but I can't figure out how to do everything I need in the correct complexity.
So here are the constraints (and the data structure which I know has it)
Inserting and Deletion in O(log n) (SortedDictionary)
Search in O(log n) (SortedDictionary & SortedList)
Iteration from one searched element to another in O(log n) + O(m) (where m is the number of elements in between) (SortedList)
As you can see, I don't know how to get SortedDictionary to do number 3. Basically what I need to do is get all the elements with a range without iterating the set.
Please tell me if my question isn't clear.
This seems to describe a B+ tree perfectly: http://en.wikipedia.org/wiki/B%2B_tree :
Inserting a record requires O(log(n)) operations in the worst case
Finding a record requires O(log(n)) operations in the worst case
Performing a range query with k elements occurring within the range requires O(log(n) + k) operations in the worst case.
A C# implementation seems to exist here: http://bplusdotnet.sourceforge.net/
I don't think there is a collection in the framework that does what you describe, although I could be wrong.
What you are looking for is a linked list that is indexed with a binary tree. This would provide you O(log n) insertion, deletion and search using the binary tree, with O(m) traversal using the linked list.
You might want to have a look at the C5 Generic Collections Library. Although there doesn't appear to be a collection that fits your description there, you might be able to marry together their TreeSet<T> and LinkedList<T> objects, creating a new SortedLinkedList<T> object.
Some of the suggestions were pretty good, but I decided to implement the collection myself (it sounded fun). I started with the .NET implementation of SortedDictionary, and heavily modified it to do what I needed it to do
Just so other people can benefit from my work, here is the class:
internal delegate void TreeWalkAction<Key, Value>(BinaryTreeSearch<Key, Value>.Node node);
internal delegate bool TreeWalkTerminationPredicate<Key, Value>(BinaryTreeSearch<Key, Value>.Node node);
internal class BinaryTreeSearch<Key, Value>
{
// Fields
private IComparer<Key> comparer;
private int count;
private Node root;
private int version;
// Methods
public BinaryTreeSearch(IComparer<Key> comparer)
{
if (comparer == null)
{
this.comparer = Comparer<Key>.Default;
}
else
{
this.comparer = comparer;
}
}
private Node First
{
get
{
if (root == null) return null;
Node n = root;
while (n.Left != null)
{
n = n.Left;
}
return n;
}
}
public Key Min
{
get
{
Node first = First;
return first == null ? default(Key) : first.Key;
}
}
public Key Max
{
get
{
if (root == null) return default(Key);
Node n = root;
while (n.Right != null)
{
n = n.Right;
}
return n.Key;
}
}
public List<Value> this[Key key]
{
get
{
Node n = FindNode(key);
return n == null ? new List<Value>() : n.Values;
}
}
public List<Value> GetRange(Key start, Key end)
{
Node node = FindNextNode(start);
List<Value> ret = new List<Value>();
InOrderTreeWalk(node,
aNode => ret.AddRange(aNode.Values),
aNode => comparer.Compare(end, aNode.Key) < 0);
return ret;
}
public void Add(Key key, Value value)
{
if (this.root == null)
{
this.root = new Node(null, key, value, false);
this.count = 1;
}
else
{
Node root = this.root;
Node node = null;
Node grandParent = null;
Node greatGrandParent = null;
int num = 0;
while (root != null)
{
num = this.comparer.Compare(key, root.Key);
if (num == 0)
{
root.Values.Add(value);
count++;
return;
}
if (Is4Node(root))
{
Split4Node(root);
if (IsRed(node))
{
this.InsertionBalance(root, ref node, grandParent, greatGrandParent);
}
}
greatGrandParent = grandParent;
grandParent = node;
node = root;
root = (num < 0) ? root.Left : root.Right;
}
Node current = new Node(node, key, value);
if (num > 0)
{
node.Right = current;
}
else
{
node.Left = current;
}
if (node.IsRed)
{
this.InsertionBalance(current, ref node, grandParent, greatGrandParent);
}
this.root.IsRed = false;
this.count++;
this.version++;
}
}
public void Clear()
{
this.root = null;
this.count = 0;
this.version++;
}
public bool Contains(Key key)
{
return (this.FindNode(key) != null);
}
internal Node FindNode(Key item)
{
int num;
for (Node node = this.root; node != null; node = (num < 0) ? node.Left : node.Right)
{
num = this.comparer.Compare(item, node.Key);
if (num == 0)
{
return node;
}
}
return null;
}
internal Node FindNextNode(Key key)
{
int num;
Node node = root;
while (true)
{
num = comparer.Compare(key, node.Key);
if (num == 0)
{
return node;
}
else if (num < 0)
{
if (node.Left == null) return node;
node = node.Left;
}
else
{
node = node.Right;
}
}
}
private static Node GetSibling(Node node, Node parent)
{
if (parent.Left == node)
{
return parent.Right;
}
return parent.Left;
}
internal void InOrderTreeWalk(Node start, TreeWalkAction<Key, Value> action, TreeWalkTerminationPredicate<Key, Value> terminationPredicate)
{
Node node = start;
while (node != null && !terminationPredicate(node))
{
action(node);
node = node.Next;
}
}
private void InsertionBalance(Node current, ref Node parent, Node grandParent, Node greatGrandParent)
{
Node node;
bool flag = grandParent.Right == parent;
bool flag2 = parent.Right == current;
if (flag == flag2)
{
node = flag2 ? RotateLeft(grandParent) : RotateRight(grandParent);
}
else
{
node = flag2 ? RotateLeftRight(grandParent) : RotateRightLeft(grandParent);
parent = greatGrandParent;
}
grandParent.IsRed = true;
node.IsRed = false;
this.ReplaceChildOfNodeOrRoot(greatGrandParent, grandParent, node);
}
private static bool Is2Node(Node node)
{
return ((IsBlack(node) && IsNullOrBlack(node.Left)) && IsNullOrBlack(node.Right));
}
private static bool Is4Node(Node node)
{
return (IsRed(node.Left) && IsRed(node.Right));
}
private static bool IsBlack(Node node)
{
return ((node != null) && !node.IsRed);
}
private static bool IsNullOrBlack(Node node)
{
if (node != null)
{
return !node.IsRed;
}
return true;
}
private static bool IsRed(Node node)
{
return ((node != null) && node.IsRed);
}
private static void Merge2Nodes(Node parent, Node child1, Node child2)
{
parent.IsRed = false;
child1.IsRed = true;
child2.IsRed = true;
}
public bool Remove(Key key, Value value)
{
if (this.root == null)
{
return false;
}
Node root = this.root;
Node parent = null;
Node node3 = null;
Node match = null;
Node parentOfMatch = null;
bool flag = false;
while (root != null)
{
if (Is2Node(root))
{
if (parent == null)
{
root.IsRed = true;
}
else
{
Node sibling = GetSibling(root, parent);
if (sibling.IsRed)
{
if (parent.Right == sibling)
{
RotateLeft(parent);
}
else
{
RotateRight(parent);
}
parent.IsRed = true;
sibling.IsRed = false;
this.ReplaceChildOfNodeOrRoot(node3, parent, sibling);
node3 = sibling;
if (parent == match)
{
parentOfMatch = sibling;
}
sibling = (parent.Left == root) ? parent.Right : parent.Left;
}
if (Is2Node(sibling))
{
Merge2Nodes(parent, root, sibling);
}
else
{
TreeRotation rotation = RotationNeeded(parent, root, sibling);
Node newChild = null;
switch (rotation)
{
case TreeRotation.LeftRotation:
sibling.Right.IsRed = false;
newChild = RotateLeft(parent);
break;
case TreeRotation.RightRotation:
sibling.Left.IsRed = false;
newChild = RotateRight(parent);
break;
case TreeRotation.RightLeftRotation:
newChild = RotateRightLeft(parent);
break;
case TreeRotation.LeftRightRotation:
newChild = RotateLeftRight(parent);
break;
}
newChild.IsRed = parent.IsRed;
parent.IsRed = false;
root.IsRed = true;
this.ReplaceChildOfNodeOrRoot(node3, parent, newChild);
if (parent == match)
{
parentOfMatch = newChild;
}
node3 = newChild;
}
}
}
int num = flag ? -1 : this.comparer.Compare(key, root.Key);
if (num == 0)
{
flag = true;
match = root;
parentOfMatch = parent;
}
node3 = parent;
parent = root;
if (num < 0)
{
root = root.Left;
}
else
{
root = root.Right;
}
}
if (match != null)
{
if (match.Values.Remove(value))
{
this.count--;
}
if (match.Values.Count == 0)
{
this.ReplaceNode(match, parentOfMatch, parent, node3);
}
}
if (this.root != null)
{
this.root.IsRed = false;
}
this.version++;
return flag;
}
private void ReplaceChildOfNodeOrRoot(Node parent, Node child, Node newChild)
{
if (parent != null)
{
if (parent.Left == child)
{
parent.Left = newChild;
}
else
{
parent.Right = newChild;
}
if (newChild != null) newChild.Parent = parent;
}
else
{
this.root = newChild;
}
}
private void ReplaceNode(Node match, Node parentOfMatch, Node succesor, Node parentOfSuccesor)
{
if (succesor == match)
{
succesor = match.Left;
}
else
{
if (succesor.Right != null)
{
succesor.Right.IsRed = false;
}
if (parentOfSuccesor != match)
{
parentOfSuccesor.Left = succesor.Right; if (succesor.Right != null) succesor.Right.Parent = parentOfSuccesor;
succesor.Right = match.Right; if (match.Right != null) match.Right.Parent = succesor;
}
succesor.Left = match.Left; if (match.Left != null) match.Left.Parent = succesor;
}
if (succesor != null)
{
succesor.IsRed = match.IsRed;
}
this.ReplaceChildOfNodeOrRoot(parentOfMatch, match, succesor);
}
private static Node RotateLeft(Node node)
{
Node right = node.Right;
node.Right = right.Left; if (right.Left != null) right.Left.Parent = node;
right.Left = node; if (node != null) node.Parent = right;
return right;
}
private static Node RotateLeftRight(Node node)
{
Node left = node.Left;
Node right = left.Right;
node.Left = right.Right; if (right.Right != null) right.Right.Parent = node;
right.Right = node; if (node != null) node.Parent = right;
left.Right = right.Left; if (right.Left != null) right.Left.Parent = left;
right.Left = left; if (left != null) left.Parent = right;
return right;
}
private static Node RotateRight(Node node)
{
Node left = node.Left;
node.Left = left.Right; if (left.Right != null) left.Right.Parent = node;
left.Right = node; if (node != null) node.Parent = left;
return left;
}
private static Node RotateRightLeft(Node node)
{
Node right = node.Right;
Node left = right.Left;
node.Right = left.Left; if (left.Left != null) left.Left.Parent = node;
left.Left = node; if (node != null) node.Parent = left;
right.Left = left.Right; if (left.Right != null) left.Right.Parent = right;
left.Right = right; if (right != null) right.Parent = left;
return left;
}
private static TreeRotation RotationNeeded(Node parent, Node current, Node sibling)
{
if (IsRed(sibling.Left))
{
if (parent.Left == current)
{
return TreeRotation.RightLeftRotation;
}
return TreeRotation.RightRotation;
}
if (parent.Left == current)
{
return TreeRotation.LeftRotation;
}
return TreeRotation.LeftRightRotation;
}
private static void Split4Node(Node node)
{
node.IsRed = true;
node.Left.IsRed = false;
node.Right.IsRed = false;
}
// Properties
public IComparer<Key> Comparer
{
get
{
return this.comparer;
}
}
public int Count
{
get
{
return this.count;
}
}
internal class Node
{
// Fields
private bool isRed;
private Node left, right, parent;
private Key key;
private List<Value> values;
// Methods
public Node(Node parent, Key item, Value value) : this(parent, item, value, true)
{
}
public Node(Node parent, Key key, Value value, bool isRed)
{
this.key = key;
this.parent = parent;
this.values = new List<Value>(new Value[] { value });
this.isRed = isRed;
}
// Properties
public bool IsRed
{
get
{
return this.isRed;
}
set
{
this.isRed = value;
}
}
public Key Key
{
get
{
return this.key;
}
set
{
this.key = value;
}
}
public List<Value> Values { get { return values; } }
public Node Left
{
get
{
return this.left;
}
set
{
this.left = value;
}
}
public Node Right
{
get
{
return this.right;
}
set
{
this.right = value;
}
}
public Node Parent
{
get
{
return this.parent;
}
set
{
this.parent = value;
}
}
public Node Next
{
get
{
if (right == null)
{
if (parent == null)
{
return null; // this puppy must be lonely
}
else if (parent.Left == this) // this is a left child
{
return parent;
}
else
{
//this is a right child, we need to go up the tree
//until we find a left child. Then the parent will be the next
Node n = this;
do
{
n = n.parent;
if (n.parent == null)
{
return null; // this must have been a node along the right edge of the tree
}
} while (n.parent.right == n);
return n.parent;
}
}
else // there is a right child.
{
Node go = right;
while (go.left != null)
{
go = go.left;
}
return go;
}
}
}
public override string ToString()
{
return key.ToString() + " - [" + string.Join(", ", new List<string>(values.Select<Value, string>(o => o.ToString())).ToArray()) + "]";
}
}
internal enum TreeRotation
{
LeftRightRotation = 4,
LeftRotation = 1,
RightLeftRotation = 3,
RightRotation = 2
}
}
and a quick unit test (which doesn't actually cover all the code, so there might still be some bugs):
[TestFixture]
public class BTSTest
{
private class iC : IComparer<int>{public int Compare(int x, int y){return x.CompareTo(y);}}
[Test]
public void Test()
{
BinaryTreeSearch<int, int> bts = new BinaryTreeSearch<int, int>(new iC());
bts.Add(5, 1);
bts.Add(5, 2);
bts.Add(6, 2);
bts.Add(2, 3);
bts.Add(8, 2);
bts.Add(10, 11);
bts.Add(9, 4);
bts.Add(3, 32);
bts.Add(12, 32);
bts.Add(8, 32);
bts.Add(9, 32);
Assert.AreEqual(11, bts.Count);
Assert.AreEqual(2, bts.Min);
Assert.AreEqual(12, bts.Max);
List<int> val = bts[5];
Assert.AreEqual(2, val.Count);
Assert.IsTrue(val.Contains(1));
Assert.IsTrue(val.Contains(2));
val = bts[6];
Assert.AreEqual(1, val.Count);
Assert.IsTrue(val.Contains(2));
Assert.IsTrue(bts.Contains(5));
Assert.IsFalse(bts.Contains(-1));
val = bts.GetRange(5, 8);
Assert.AreEqual(5, val.Count);
Assert.IsTrue(val.Contains(1));
Assert.IsTrue(val.Contains(32));
Assert.AreEqual(3, val.Count<int>(num => num == 2));
bts.Remove(8, 32);
bts.Remove(5, 2);
Assert.AreEqual(9, bts.Count);
val = bts.GetRange(5, 8);
Assert.AreEqual(3, val.Count);
Assert.IsTrue(val.Contains(1));
Assert.AreEqual(2, val.Count<int>(num => num == 2));
bts.Remove(2, 3);
Assert.IsNull(bts.FindNode(2));
bts.Remove(12, 32);
Assert.IsNull(bts.FindNode(12));
Assert.AreEqual(3, bts.Min);
Assert.AreEqual(10, bts.Max);
bts.Remove(9, 4);
bts.Remove(5, 1);
bts.Remove(6, 2);
}
}
Check out System.Collections.ObjectModel.KeyedCollection<TKey, TItem> - it might not suit your requirements but it seems like a good fit, as it provides an internal lookup dictionary that enables O(1) retrieval of items by index and approaching O(1) by key.
The caveat is that it is intended to store objects where the key is defined as a property on the object, so unless you can mash your input data to fit, it won't be appropriate.
I would include some more information on what data you are intending to store and the volume, as this might help provide alternatives.

Categories

Resources