Im implementing a stack using a linked list. I am having trouble with my pop method where tail.previous is null. I think this is because im trying to assign to the node after the tail which doesnt exist. if this is the case, how can i fix it.
class DynamicStack<T>
{
private class Node
{
public T element { get; private set; }
public Node Next { get; set; }
public Node Previous { get; set; }
public Node(T element, Node prevNode)
{
this.element = element;
Next = null;
Previous = null;
if (prevNode != null)
prevNode.Next = this;
}
}
private Node head, tail;
public int Count { get; private set; }
public DynamicStack()
{
this.head = null;
this.tail = null;
this.Count = 0;
}
public T Pop()
{
if (Count == 0)
return default(T);
Node temp = tail;
tail = tail.Previous;
Count--;
return temp.element;
}
}
I have tried doing the pop method as below but it doesnt follow LIFO so its not correct.
public T Pop()
{
if (Count == 0)
return default(T);
Node temp = head;
head = head.Next;
Count--;
return temp.element;
}
Related
I keep getting an unhandled exception
"Object reference not set to an instance of an object"
for the following code, specifically on the line temp.next = node. Can anyone help me figure out why?
The code below is a class for birds where the user inputs a name and the addBird method is suppose to add the name to the end of the linked list.
class BirdsSurve {
private Node first;
public class Node
{
public string Name { get; set; }
public int count { get; set; }
public Node next;
public Node()
{
this.count = 1;
}
public void setNext(Node Next)
{
next = Next;
}
public int addCount()
{
count++;
return count;
}
}
public BirdsSurvey()
{
this.first = null;
}
public void addBird(string bird)
{
Node node = new Node();
node.Name = bird;
if (first == null)
{ first = node; }
else
{
Node temp = first;
while (temp != null)
{
if (temp.Name == bird)
{ temp.addCount(); }
if (temp.next == null)
{
temp = temp.next;
temp.next = node; }
// temp = temp.next;
}
}
}
You set temp to temp.next within the if clause, which checks, if temp.next is null. So, you basically set temp to be null. So, you get the error, because you try to get a next property from a variable, which is null and not an object.
As a side note, maybe rethink the naming of your variables, so that they are not all the same, because that can become confusing quite fast.
I have created custom linked list in c#.
LinkedList.cs:
class LinkedList
{
private Node Start;//Mazgas pr
private Node End;//Mazgas pb
private Node Current;// Mazas d saraso sasajai
public LinkedList()
{
this.Start = null;
this.End = null;
this.Current = null;
}
public Object Get(int index)
{
for( Node curr = Start; curr != null; curr = curr.Next)
{
if( curr.Index == index )
return curr.Data;
}
return null;
}
public void PrintData()
{
for (Node curr = Start; curr != null; curr = curr.Next)
{
Console.WriteLine("{0}: {1}", curr.Index, curr.Data);
}
}
public int Count()
{
int i = 0;
for( Node curr = Start; curr != null; curr = curr.Next, i++);
return i;
}
public void Add(Object data)
{
Node current = new Node(data, null);
if (Start != null)
{
End.Next = current;
End.Next.Index = End.Index + 1;
End = current;
}
else
{
Start = current;
End = current;
End.Index = 0;
}
}
}
Node.cs:
class Node
{
public Object Data { get; set; }
public Node Next { get; set; }
public int Index { get; set; }
public Node() { }
public Node(Object data, Node next )
{
Data = data;
Next = next;
}
public override string ToString ()
{
return string.Format ("Data: {0}", Data);
}
}
and Part.cs
class Part
{
public string Code { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public Part(string code, string name, double price)
{
Code = code;
Name = name;
Price = price;
}
public Part() { }
public override string ToString()
{
return string.Format("{0} {1}", Name, Code);
}
}
Problem is, when i create list LinkedList parts = new LinkedList()
and add objects to it parts.Add(new Part("code", "name", 10)); i can't access Part object variables. I need to do this:
for( int i=0; i<parts.Count(); i++)
{
Console.WriteLine("{0}", (Part)Parts.Get(i).Name);
}
but it gives me error:
Error CS1061: Type 'object' does not contain a definition for 'Name'
and no extension method 'Name' of type 'object' could be found. Are
you missing an assembly reference? (CS1061)
EDITED: I need this linked list to be flexible for any type of object.
(Part)Parts.Get(i).Name is equivalent to (Part)(Parts.Get(i).Name) and since return value of your Get(i) is of type object and object doesn't have Name property, you received the exception.
You can correct it this way:
((Part)Parts.Get(i)).Name
Note:
I suppose it's just for learning purpose.
If all items of the list are of the same type, you can make your Generic classes. Having a generic Node<T> and LinkedList<T> class you can change the input parameters and return values to T instead of object.
In a real application, you can use LinkedList<T> or other generic data structures available.
I'm new at this and trying to write this code for a queue but it doesn't work. I'm stuck, I wrote queue for a linked list and I can't find where I'm wrong here, any help is great. Thank you in advance.
class Queue
{
public Node<T> head { get; set; }
public Node<T> tail { get; set; }
public int size { get; set; }
public Queue()
{
head = null;
tail = null;
}
public void Enqueue(T value)
{
if (head == null)
{
head = new Node<T>(value);
tail = head;
}
else
{
tail.sljedeci = new Node<T>(value);
tail = tail.next;
}
size++;
}
public T Dequeue()
{
if (size == 0)
{
throw new IndexOutOfRangeException();
}
else if (size == 1)
{
T value = head.value;
size--;
head = tail = null;
return value;
}
else
{
T value = head.value;
head = head.next;
size--;
return value;
}
}
public void Peek()
{
if (size == 0)
{
Console.WriteLine("List is empty");
}
else
{
Node<T> temp = head;
Console.Write("{ ");
while (temp.next != null)
{
Console.Write("{0}, ", temp.value);
temp = temp.next;
}
Console.Write(temp.valuet + " }");
}
}
I am trying to implement a basic Binary search tree.
I was able to create a Node and I have problems with the AddNode() function. It is supposed to add a new node to the existing tree but it replaces it.
Any ideas what should be done in the AddNode() function ?
class Node
{
public int value { get; set; }
public Node left { get; set; }
public Node right { get; set; }
public Node(int i)
{
this.value = i;
this.left = null;
this.right = null;
}
}
class Tree
{
public Node root { get; set; }
public Tree(Node n)
{
root = n;
}
public void AddNode(int valueToBeInserted)
{
if (this.root == null)
{
this.root = new Node(valueToBeInserted);
// problem here : existing tree is destroyed.
// a new one is created.
// instead it should add a new node to the end of the tree if its null
}
if (valueToBeInserted < this.root.value)
{
this.root = this.root.left;
this.AddNode(valueToBeInserted);
}
if (valueToBeInserted > this.root.value)
{
this.root = this.root.right;
this.AddNode(valueToBeInserted);
}
}
public void printTree()
{
// print recursively the values here.
}
}
class TreeTest
{
public void Test()
{
var tree = new Tree(new Node(100));
tree.AddNode(20);
tree.AddNode(100);
}
}
Thanks.
These lines replace the root:
this.root = this.root.left;
this.root = this.root.right;
You should instead pass a parameter to your recursive function.
You can also remove the this quantifiers - they're only necessary when you have a local variable with the same name or perhaps in some other corner cases.
Adding a helper function is useful / necessary since the root must be catered for separately.
Updated code:
public void AddNode(int valueToBeInserted)
{
if (root == null)
{
root = new Node(valueToBeInserted);
}
else
{
AddNode(valueToBeInserted, root);
}
}
private void AddNode(int valueToBeInserted, Node current)
{
if (valueToBeInserted < current.value)
{
if (current.left == null)
current.left = new Node(valueToBeInserted);
else
AddNode(valueToBeInserted, current.left);
}
if (valueToBeInserted > current.value)
{
if (current.right == null)
current.right = new Node(valueToBeInserted);
else
AddNode(valueToBeInserted, current.right);
}
}
This statement will only be true the first time you run your code.
if (this.root == null)
{
this.root = new Node(valueToBeInserted);
}
Nowhere does the this.root get set to null again...
Normally you would code the add like this:
public void AddNode(int valueToBeInserted)
{
if (this.root == null)
{
this.root = new Node(valueToBeInserted);
}
if (valueToBeInserted < this.root.value)
{
this.root.left = this.AddNode(valueToBeInserted);
this.root = this.root.left;
}
if (valueToBeInserted > this.root.value)
{
this.root.right = this.AddNode(valueToBeInserted);
this.root = this.root.right;
}
}
I have the following list:
public class MyQueue : IEnumerable<int>
{
private Node Head { get; set; }
private Node Tail { get; set; }
public MyQueue()
{
Head = null;
}
public void Add(int item)
{
Enqueue(item);
}
public void Enqueue(int item)
{
var newItem = new Node { Data = item };
if (Head == null)
{
Head = newItem;
Tail = newItem;
return;
}
Node last = Tail;
last.Next = newItem;
Tail = newItem;
}
public IEnumerator<int> GetEnumerator()
{
Node current = Head;
while (current != null)
{
yield return current.Data;
current = current.Next;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
private class Node
{
public int Data;
public Node Next;
}
}
There are other methods, but they do not matter in this scenario.
I'd like to add indexing to this list.
So I can do something like:
var q = new MyQueue() {1, 2};
Console.WriteLine(q[0]); //1
What do I need to implement?
you need to make a property like this:
public int this[int index]
{
get {
// code to return value
}
}
public int this[int index]
{
get
{
return this.Skip(index).FirstOrDefault();
}
}
You need to implement an indexer. An indexer enables you to access a class, struct or interface as if it were an array. The syntax is as follows:
public int this[int index] {
get {
// obtain the item that corresponds to this index
// return the item
}
set {
// set the value of the item that corresponds to
// index to be equal to the implicit parameter named "value"
}
}
Here's an explicit example for your case:
public class MyQueue : IEnumerable<int> {
// ...
public int this[int index] {
get {
if (index < 0 || index > this.Count() - 1) {
throw new ArgumentOutOfRangeException("index");
}
return this.Skip(index).First();
}
set {
if (index < 0) {
throw new ArgumentOutOfRangeException("index");
}
Node current = Head;
int i = 0;
while (current != null && i < index) {
current = current.Next; i++;
}
if (current == null) {
throw new ArgumentOutOfRangeException("index");
}
current.Data = value;
}
}
}
Implement the this operator.
Write a this property, like this: (pun intended)
public int this[int index] {
get {
return something;
}
//Optionally:
set {
something = value;
}
}
Also, you should probably implement IList<int>. (Note, though, that the Count property would require a loop)