C# Linked List enqueue and dequeue method syntax - c#

I have a project that requires us to use linked list stacks(NodeStack) and queues(NodeQueue). I have this sample code to work with:
class Node
{
object value;
Node next;
public void setValue(object o)
{
value = o;
}
public object getValue()
{
return value;
}
public void setNext(Node o)
{
next = o;
}
public Node getNext()
{
return next;
}
}
class NodeStack
{
Node top;
int count;
public void Push(object o)
{
Node newTop = new Node();
newTop.setValue(o);
newTop.setNext(top);
top = newTop;
count = count + 1;
}
public object Pop()
{
object value = top.getValue();
top = top.getNext();
return value;
}
public object Peek()
{
return top.getValue();
}
public void Clear()
{
top = null;
count = 0;
}
public int Count()
{
return count;
}
}
From this code I should be able to derive the NodeStack to a NodeQueuebut I have trouble understanding the syntax for the Enqueue and Dequeue methods. When I run a simple enqueue and dequeue program I get a Null reference exception on the 1st line of the dequeue method. Really appreciate the help.
Code I have so far:
class NodeQueue
{
Node tail;
Node head;
int count;
public void Enqueue(object o)
{
if (head == null)
{
Node newHead = new Node();
newHead.setValue(o);
head = tail = newHead;
newHead.setNext(tail);
}
else
{
Node newTail = new Node();
newTail.setValue(o);
newTail.setNext(tail);
tail = newTail;
}
count++;
}
public object Dequeue()
{
object value = head.getValue();
head = head.getNext();
return value;
}
public void Clear()
{
head = null;
tail = null;
count = 0;
}
public int Count()
{
return count;
}
}
EDIT:
The problem with the NullException has been handled but now I have a problem with dequeue. I am using this program to test the queue
NodeQueue nq = new NodeQueue();
nq.Enqueue(1);
nq.Enqueue(2);
nq.Enqueue(3);
nq.Enqueue(4);
nq.Enqueue(5);
Console.WriteLine(nq.Dequeue());
Console.WriteLine(nq.Dequeue());
Console.WriteLine(nq.Dequeue());
Console.WriteLine(nq.Dequeue());
Console.WriteLine(nq.Dequeue());
Console.ReadLine();
The expected output would be 1..5. The output that happens though is that 1 keeps getting printed.

Your Enqueuemethod is not correct thats why your are getting exception in 'Dequeue`
Also in Dequeue you should reduce count by one.
In your Enqueue head is not set.
class NodeQueue
{
Node tail;
Node head;
int count;
public void Enqueue(object o)
{
if (head == null)
{
Node newHead = new Node();
newHead.setValue(o);
head = tail = newHead;
}
else
{
Node newTail = new Node();
newTail.setValue(o);
tail.setNext(newTail);
tail = newTail;
}
count++;
}
public object Dequeue()
{
if (null != head)
{
object value = head.getValue();
head = head.getNext();
count--;
return value;
}
return null;
}
public void Clear()
{
head = null;
tail = null;
count = 0;
}
public int Count()
{
return count;
}
}

Related

LinkedList .Add() only runs once

I'm making a basic LinkedList following this tutorial. However, when I'm done the list only contains two elements, "first" and "fourth". I put some break points in the code and found that the Add function of the LinkedList class only runs once. Each succesive Add goes into the Node(object data) method of the Node class. Any idea what I'm doing wrong?
public class Node
{
public object data;
public Node next;
public Node(object data)
{
this.data = data;
}
}
public class LinkedList
{
private Node head;
private Node current;
public void Add(Node n)
{
if (head == null)
{
head = n;
current = head;
}
else
{
current.next = n;
current = current.next;
}
}
}
class Program
{
static void Main(string[] args)
{
LinkedList list = new LinkedList();
list.Add(new Node("first"));
list.Add(new Node("second"));
list.Add(new Node("third"));
list.Add(new Node("fourth"));
}
}
Using this basic print method with your code :
public void Print()
{
Node curr = head;
while(true)
{
if(curr == null)
return;
Console.WriteLine(curr.data.ToString());
curr = curr.next;
}
}
Return the correct result : live example.
first
second
third
fourth
Your error must be with your printing routine.
There is no problem with your code, i guess you are checking only the LinkedList nodes while debugging, which will only shows the head and the current values.
Just try this,
class Program
{
static void Main(string[] args)
{
LinkedList list = new LinkedList();
list.Add(new Node("first"));
list.Add(new Node("second"));
list.Add(new Node("third"));
list.Add(new Node("fourth"));
list.PrintNodes();
}
}
public class Node
{
public object data;
public Node next;
public Node(object data)
{
this.data = data;
}
}
public class LinkedList
{
private Node head;
private Node current;
public void Add(Node n)
{
if (head == null)
{
head = n;
current = head;
}
else
{
current.next = n;
current = current.next;
}
}
public void PrintNodes()
{
while (head != null)
{
Console.WriteLine(head.data);
head = head.next;
}
Console.ReadLine();
}
}

Make Length property available for my class C#

I want to create class Massive and to add a method for adding two massives. But property Length for my class instances doesn't work.
public static void Add(Massiv mas1, Massiv mas2, ref Massiv mas3)
{
if (mas1.Length != mas2.Length)
{
Console.WriteLine("Error!"); return;
}
for (int i = 0; i < mas.Length; ++i)
{
mas3[i] = mas1[i] + mas2[i];
}
}
How to make it available for my class?
It's my code.
class Massiv
{
public Massiv(int n)
{
mas = new int[n];
Random rand = new Random();
for (int i = 0; i < mas.Length; ++i)
{
mas[i] = rand.Next(0, 10);
}
}
public void ShowAll()
{
Console.WriteLine("Massive: ");
foreach (var elem in mas)
{
Console.Write(elem + " ");
}
Console.WriteLine();
}
public void ShowElement(int index)
{
try
{
Console.WriteLine("mas[{0}] = {1}", index, mas[index]);
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("Error!");
}
}
public static void Add(Massiv mas1, Massiv mas2, ref Massiv mas3)
{
if (mas1.Length != mas2.Length)
{
Console.WriteLine("Error!"); return;
}
for (int i = 0; i < mas.Length; ++i)
{
mas3[i] = mas1[i] + mas2[i];
}
}
public int this[int index]
{
get { return mas[index]; }
set { mas[index] = value; }
}
private int[] mas;
}
}
It seems like you have not declared any Length property, therefore, the compiler cannot possibly know one.
Basically, add this to your class:
public int Length {
get {
}
set {
}
}
In the getter, you need to return the value of the property, while in the setter, you will have to change it.
In this case, you seem to want to retrieve the length of your internal array. If you do not need write-access, you can skip the set part:
public int Length {
get {
return mas.Length;
}
}
Just add this property to your class:
public int Length {
get { return mas.Length; }
}
Note it has only a get accessor, which makes it read only (You don't seem to need write access since you initialize the private array in the constructor).
public int Length {
get {
return mas.Length;
}
}

unable to add a node in avl_tree

I have written a code in C# for the implementation of AVL_trees. I am having some problems with nodes that's why I am unable to insert data in the nodes. Below is my code.
public class avl_node
{
public int Data;
public avl_node Left;
public avl_node Right;
public int height;
public void DisplayNode()
{
Console.Write("{0}", Data);
}
}
public class avl_tree
{
public avl_node root;
public avl_tree()
{
root = null;
}
public void Insert(int i)
{
avl_node newNode = new avl_node();
newNode.Data = i;
newNode.height = newNode.height + 1;
if (root == null)
{
root = newNode;
}
else
{
avl_node current = root;
avl_node parent;
while (true)
{
parent = current;
if (i < current.Data)
{
current = current.Left;
if (current == null)
{
parent.Left = newNode;
break;
}
else
{
current = current.Right;
if (current == null)
{
parent.Right = newNode;
break;
}
}
}
}
}
}
public void InOrder(avl_node node)
{
if (!(node == null))
{
InOrder(node.Left);
node.DisplayNode();
InOrder(node.Right);
}
}
}
class Program
{
static void Main(string[] args)
{
avl_tree nums = new avl_tree();
nums.Insert(23);
nums.Insert(45);
nums.Insert(16);
nums.Insert(37);
nums.Insert(3);
nums.Insert(99);
nums.Insert(22);
avl_node nd = new avl_node();
nd = nums.Search(37);
Console.WriteLine("Inorder traversal: ");
nums.InOrder(nums.root);
}
}
All I get is a black console screen. I am very confused.
Hoping for a better response.
Regards
Umer
"All I get is a black console screen"
After 23 is inserted, your Insert() method gets stuck in the while loop because 45 is never less than 23:
while (true)
{
parent = current;
if (i < current.Data)
// you never get in here, so we just loop around in "while (true)"
Take a look at that loop in the insert method, you will get stuck in the loop everytime you try to insert any value greater than existing values already in the tree.
It will happen because of this conditional: if(i < current.data).
Where is the else statement? You put it inside the scope of the mentioned conditional. So it will never be reached, thus the program will run the infinite loop.
You should put an "}" before the else statement, so that else will be outside the scope of the first if statement. And Remove one of the "}" at the end of the method.
That way it should run just fine.

Can this code be refactored by using the reactive framework?

copy paste the following code in new C# console app.
class Program
{
static void Main(string[] args)
{
var enumerator = new QueuedEnumerator<long>();
var listenerWaitHandle = Listener(enumerator);
Publisher(enumerator);
listenerWaitHandle.WaitOne();
}
private static AutoResetEvent Listener(IEnumerator<long> items)
{
var #event = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem((o) =>
{
while (items.MoveNext())
{
Console.WriteLine("Received : " + items.Current);
Thread.Sleep(2 * 1000);
}
(o as AutoResetEvent).Set();
}, #event);
return #event;
}
private static void Publisher(QueuedEnumerator<long> enumerator)
{
for (int i = 0; i < 10; i++)
{
enumerator.Set(i);
Console.WriteLine("Sended : " + i);
Thread.Sleep(1 * 1000);
}
enumerator.Finish();
}
class QueuedEnumerator<T> : IEnumerator<T>
{
private Queue _internal = Queue.Synchronized(new Queue());
private T _current;
private bool _finished;
private AutoResetEvent _setted = new AutoResetEvent(false);
public void Finish()
{
_finished = true;
_setted.Set();
}
public void Set(T item)
{
if (_internal.Count > 3)
{
Console.WriteLine("I'm full, give the listener some slack !");
Thread.Sleep(3 * 1000);
Set(item);
}
else
{
_internal.Enqueue(item);
_setted.Set();
}
}
public T Current
{
get { return _current; }
}
public void Dispose()
{
}
object System.Collections.IEnumerator.Current
{
get { return _current; }
}
public bool MoveNext()
{
if (_finished && _internal.Count == 0)
return false;
else if (_internal.Count > 0)
{
_current = (T)_internal.Dequeue();
return true;
}
else
{
_setted.WaitOne();
return MoveNext();
}
}
public void Reset()
{
}
}
}
2 threads (A,B)
A thread can provide one instance at a time and calls the Set method
B thread wants to receive a sequence of instances (provided by thread A)
So literally transforming an Add(item), Add(item), .. to a IEnumerable between different threads
Other solutions also welcome of course!
Sure - this code might not be the best way to do it, but here was my initial stab at it:
Subject<Item> toAddObservable;
ListObservable<Item> buffer;
void Init()
{
// Subjects are an IObservable we can trigger by-hand, they're the
// mutable variables of Rx
toAddObservable = new Subject(Scheduler.TaskPool);
// ListObservable will hold all our items until someone asks for them
// It will yield exactly *one* item, but only when toAddObservable
// is completed.
buffer = new ListObservable<Item>(toAddObservable);
}
void Add(Item to_add)
{
lock (this) {
// Subjects themselves are thread-safe, but we still need the lock
// to protect against the reset in FetchResults
ToAddOnAnotherThread.OnNext(to_add);
}
}
IEnumerable<Item> FetchResults()
{
IEnumerable<Item> ret = null;
buffer.Subscribe(x => ret = x);
lock (this) {
toAddObservable.OnCompleted();
Init(); // Recreate everything
}
return ret;
}

See any problems with this C# implementation of a stack?

I wrote this quickly under interview conditions, I wanted to post it to the community to possibly see if there was a better/faster/cleaner way to go about it. How could this be optimized?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Stack
{
class StackElement<T>
{
public T Data { get; set; }
public StackElement<T> Below { get; set; }
public StackElement(T data)
{
Data = data;
}
}
public class Stack<T>
{
private StackElement<T> top;
public void Push(T item)
{
StackElement<T> temp;
if (top == null)
{
top = new StackElement<T>(item);
}
else
{
temp = top;
top = new StackElement<T>(item);
top.Below = temp;
}
}
public T Pop()
{
if (top == null)
{
throw new Exception("Sorry, nothing on the stack");
}
else
{
T temp = top.Data;
top = top.Below;
return temp;
}
}
public void Clear()
{
while (top != null)
Pop();
}
}
class TestProgram
{
static void Main(string[] args)
{
Test1();
Test2();
Test3();
}
private static void Test1()
{
Stack<string> myStack = new Stack<string>();
myStack.Push("joe");
myStack.Push("mike");
myStack.Push("adam");
if (myStack.Pop() != "adam") { throw new Exception("fail"); }
if (myStack.Pop() != "mike") { throw new Exception("fail"); }
if (myStack.Pop() != "joe") { throw new Exception("fail"); }
}
private static void Test3()
{
Stack<string> myStack = new Stack<string>();
myStack.Push("joe");
myStack.Push("mike");
myStack.Push("adam");
myStack.Clear();
try
{
myStack.Pop();
}
catch (Exception ex)
{
return;
}
throw new Exception("fail");
}
private static void Test2()
{
Stack<string> myStack = new Stack<string>();
myStack.Push("joe");
myStack.Push("mike");
myStack.Push("adam");
if (myStack.Pop() != "adam") { throw new Exception("fail"); }
myStack.Push("alien");
myStack.Push("nation");
if (myStack.Pop() != "nation") { throw new Exception("fail"); }
if (myStack.Pop() != "alien") { throw new Exception("fail"); }
}
}
}
I think the Clear() method could be sped up significantly by changing it to top = null;. The entire stack will be garbage collected, and no loop required in the mean time.
You could simply use an array. The .NET array methods are really fast.
public class Stack<T>
{
private const int _defaultSize = 4;
private const int _growthMultiplier = 2;
private T[] _elements;
private int _index;
private int _limit;
public Stack()
{
_elements = new T[_defaultSize];
_index = -1;
_limit = _elements.Length - 1;
}
public void Push(T item)
{
if (_index == _limit)
{
var temp = _elements;
_elements = new T[_elements.Length * _growthMultiplier];
_limit = _elements.Length - 1;
Array.Copy(temp, _elements, temp.Length);
}
_elements[++_index] = item;
}
public T Pop()
{
if (_index < 0)
throw new InvalidOperationException();
var item = _elements[_index];
_elements[_index--] = default(T);
return item;
}
public void Clear()
{
_index = -1;
Array.Clear(_elements, 0, _elements.Length);
}
}
Might be preferable to use dynamic array as the data structure instead of a linked list. The array will have better locality of reference because the elements are next to each other. A stack doesn't need ability to delete elements in the middle, splicing etc. so an array suffices.

Categories

Resources