Related
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);
}
}
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.
OK I'm having a problem, I just can't seem to get this to work, no matter what I try. The problem is everytime I write to Console I get an error:
Argument 1: cannot convert from 'void' to 'bool'
However, there is no boolean data from what I can see, bar the conditions.
class Link
{
private int data;
private Link next;
public Link(int item) //constructor with an item
{
data = item;
next = null;
}
public Link(int item, Link list) //constructor with item and list
{
data = item;
next = list;
}
public int Data //property for data
{
set { this.data = value; }
get { return this.data; }
}
public Link Next //property for next
{
set { this.next = value; }
get { return this.next;}
}
}
}
All my other methods work i.e. Display item, count the number of items etc. But what seems to be the problem:
class LinkList
{
private Link list = null; //default value – empty list
public void AddItem(int item) //add item to front of list
{
list = new Link(item, list);
}
public string DisplayItems() //write items to string and return
{
Link temp = list;
string buffer = "";
while (temp != null) // move one link and add head to the buffer
{
buffer += temp.Data + "";
temp = temp.Next;
}
return buffer;
}
public int NumberOfItems() // returns number of items in list
{
Link temp = list;
int count = 0;
while (temp != null) // move one link and add 1 to count
{
count++;
temp = temp.Next;
}
return count;
}
public void RemoveItem(int item)
{
Link current = list;
Link previous = null;
while (current != null)
{
if (current.Data == item)
{
if (previous != null)
{
previous.Next = current.Next;
current = current.Next;
}
else
{
previous = current;
current = current.Next;
list = current;
}
}
else
previous = current;
current= current.Next;
}
}
public bool IsPresent(int item)
{
Link temp = list;
bool result = false;
while (temp != null)
{
if (temp.Data == item)
{
result = true;
break;
}
else
{
temp = temp.Next;
}
}
return result;
}
}
This is my program class I use to print to console-
class Program
{
static void Main(string[] args)
{
LinkList testList = new LinkList();
testList.AddItem(10);
testList.AddItem(20);
testList.AddItem(30);
testList.AddItem(40);
testList.AddItem(50);
testList.AddItem(60);
System.Console.WriteLine("Number of Items " + testList.NumberOfItems());
System.Console.WriteLine("Display Items " + testList.DisplayItems());
System.Console.WriteLine("10 is Present " + testList.IsPresent(10));
System.Console.WriteLine("20 is Present " + testList.IsPresent(20));
System.Console.WriteLine("30 is Present " + testList.IsPresent(30));
System.Console.WriteLine("40 is Present " + testList.IsPresent(40));
System.Console.WriteLine("50 is Present " + testList.IsPresent(50));
System.Console.WriteLine("60 is Present " + testList.IsPresent(60));
System.Console.WriteLine(testList.RemoveItem(10));
System.Console.ReadLine();
Console.ReadKey();
}
}
But the RemoveItem method giving me grief, could someone please possibly help me out? Thank you.
This is the bit of code giving me a problem-
public void RemoveItem(int item)
{
Link current = list;
Link previous = null;
while (current != null)
{
if (current.Data == item)
{
if (previous != null)
{
previous.Next = current.Next;
current = current.Next;
}
else
{
previous = current;
current = current.Next;
list = current;
}
}
else
previous = current;
current= current.Next;
}
}
Thank you.
You have a problem at
System.Console.WriteLine(testList.RemoveItem(10));
since RemoveItem doesn't return any value:
// void - the method doesn't return any value
public void RemoveItem(int item)
{
...
}
you can't print it out. Just call RemoveItem and do not WriteLine:
testList.RemoveItem(10);
A better approach is to re-design RemoveItem and let it return bool (if item has been removed):
public bool RemoveItem(int item) {
...
}
You've touched on your own problem. You are trying to print the output of RemoveItem on this line:
System.Console.WriteLine(testList.RemoveItem(10));
But RemoveItem doesn't have any output since it has a return value of void. But void doesn't mean "ignore this method". Console.WriteLine still expects a value, but the value it is given isn't something it can do anything with, hence the error.
You need to either remove the print call:
RemoveItem(10);
System.Console.Writeline("10 removed.");
Or change RemoveItem to return a value:
public bool RemoveItem(int item)
{
...
return true;
}
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();
}
}
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.