class IntNode
{
public int value { get; set; }
public IntNode next { get; set; }
public IntNode(int value)
{
this.value = value;
this.next = null;
}
public IntNode(int value, IntNode next)
{
this.value = value;
this.next = next;
}
public bool HasNext ()
{
return (this.next != null);
}
public override string ToString()
{
if (this.HasNext())
return this.value + " --> " + this.next;
else
return this.value + ". [end]";
}
}
If I am getting the first node of a list, how can I sort the list from smallest to highest?
Example:
for the list
5,-4,8,12,5,71,13,0
that list will be returned
-4,0,5,5,8,12,13,71
I have tried to do it but I can`t figure it out... Thanks!
What I have tried:
static IntNode Sort (IntNode head)
{
IntNode pos = head.next;
IntNode max = head;
IntNode current = head;
while (current != null)
{
while (pos != null)
{
if (pos.value > max.value) max = pos;
pos = pos.next;
}
head.next = max.next;
max.next = head;
head = max;
pos = current;
max = current;
current = current.next;
}
return head;
}
this is my homeword so pls help.
First, you need to be clear about your idea of how the algorithm for sorting is supposed to work. It helps to write it down in normal language.
From your code I see that you wander through your list and try to compare the current item with the next. That sounds like the right approach. The condition is right but the moving of values does not work in you solution.
if (pos.value > max.value)
The basic idea of sorting is moving the items.
In other words :
while it is not sorted yet and while the next element is not null and if the current item is larger than the next exchange the values then move to the next element and do it again.
// in the beginning you only need one helping IntNode variable
IntNode current = head;
// and a flag to stop the sorting
bool sorted = false;
I would suggest to switch the values
// the condition for the comparison
if (current.value > current.next.value)
{
int temp = current.value;
current.value = current.next.value;
current.next.value = temp;
// set the flag the a sort procedure has been made as indicator that it might still not be sorted
sorted = false;
}
The rest are 2 while-loops and a boolean variable to stop the outer loop.
EDIT:
Since you seem to have figured it out on your own, for the sake of completeness here is my version of the sorting method:
public static IntNode Sort(IntNode head)
{
IntNode current = head;
bool sorted = false;
while (!sorted)
{
// assume that at this run you actually finished your sorting job
sorted = true;
// set the current element to the first position
current = head;
while (current.next != null)
{
if (current.value > current.next.value)
{
int temp = current.value;
current.value = current.next.value;
current.next.value = temp;
// apparently you found an element that was not sorted, so you might not be done yet
sorted = false;
}
// move one element forward
current = current.next;
}
}
return head;
}
Implement the IComparable interface on your class.
class IntNode : IComparable {
// ...
public int CompareTo(object obj) {
if (obj == null) return 1;
IntNode otherNode = obj as IntNode ;
if (otherNode != null)
return this.value.CompareTo(otherNode.value);
else
throw new ArgumentException("Object is not an IntNode");
}
}
Put all your nodes into a list, then use the Sort method.
var allNodes = new List<IntNode>();
// add nodes to list ...
allNodes.Sort();
Related
I am trying to rotate a doubly linked list both clockwise and counter clockwise. However my code only outputting a part of the list. I understand that the list should not rotate if there are 0 or 1 elements. I would like to rotate to the right if the value is greater than 1. Also, I would like to rotate to the left if the value is less than 0. I'm not sure what I have done wrong with my list. The logic is very confusing. The addLast method has intentionally not been included since it works.
public class Node
{
public Node next;
public Node previous;
public Object data;
}
public class LinkedList
{
private Node head;
private Node tail;
public Node rotate(int k)
{
if (head == null )
{
return head;
}
Node node = head;
k = k % listSize(head);
if (k == 0 || k == 1)
{
return head;
}
//Rotates
while (node != null && k > 1)
{
node = node.next;
k--;
}
Node newhead = node.next;
newhead.previous = null;
node.next = null;
Node temp = newhead;
while (temp.next != null)
{
temp = temp.next;
}
newhead = head;
node.previous = temp.previous;
tail = node;
return newhead;
}
public int listSize(Node node)
{
if(node == null)
{
return 0;
}
int count = 0;
while(node != null)
{
count++;
node = node.next;
}
return count;
}
public void addLast(Object data)
{
Node toAdd = new Node();
toAdd.data = data;
toAdd.next = null;
if (head == null)
{
head = toAdd;
tail = null;
}
else
{
if (tail == null)
{
head.next = toAdd;
tail = toAdd;
}
else
{
tail.next = toAdd;
tail = toAdd;
}
}
}
}
static void Main(string[] args)
{
Console.WriteLine("Add Last: ");
LinkedList myList2 = new LinkedList();
myList2.addLast("Tim");
myList2.addLast("Nick");
myList2.addLast("Julie");
myList2.addLast("Jessie");
myList2.addLast("Jordan");
myList2.addLast("Peter");
myList2.addLast("John");
myList2.rotate(2);
}
Edit: I have tried rewriting my code before reading any comments. It still does rotate the list successfully.
Yes, it's tough, and I had many of the same problems. One thing that helped was renaming some of the variables to make it clear in my head what was going on.
In the rotate function:
public Node rotate(int k)
{
if (head == null)
{
return head;
}
k = -k;
k = k % listSize(head);
if (k<0) { k+= listSize(head); }
if (k == 0 )
{
return head;
}
//Rotates
Node newhead = head;
while (newhead != null && k > 0)
{
newhead = newhead.next;
k--;
}
Node newtail = newhead.previous;
newhead.previous = null;
newtail.next = null;
tail.next = head;
head.previous = tail;
head = newhead;
tail = newtail;
return newhead;
}
(This assumes you're keeping the tail updated in addLast(). If you are, you may as well use it. Here's what I had:)
public void addLast(Object inData)
{
Node node = new Node();
node.next = null;
node.data = inData;
node.previous = tail;
if (head == null)
{
head = node;
}
if (tail != null)
{
tail.next = node;
}
tail = node;
}
I hope this is clearer.
One of the things I think you're missing is that anytime you set one nodes Next property, you should also set the corresponding next node's Previous property. Just doing that may help with the list navigation.
Otherwise, it can be helpful to break down the tasks into more discreet methods, so there's not too much going on in one method.
One thing that may be helpful, for example, is to add a method that returns a node at a specific index. This allows us to easily grab a node and set it to the new Head, which means our Rotate method doesn't need a loop - it just gets the node at the appropriate index and sets that node as the new head.
Note that setting a node as a new Head node should also be broken out into a new method, since there's a fair amount involved there as well (a new head means a new tail, and lots of Previous and Next properties to think about).
Hopefully this implementation based on your code is instructive. Please let me know if something doesn't make sense:
public class Node
{
public object Data { get; set; }
public Node Next { get; set; }
public Node Previous { get; set; }
public Node(object data)
{
Data = data;
}
public override string ToString()
{
return Data.ToString();
}
}
public class LinkedList
{
public Node Head { get; private set; }
public Node Tail { get; private set; }
public int Count
{
get
{
var count = 0;
for (var n = Head; n != null; n = n.Next, count++) ;
return count;
}
}
private void AddFirst(object data)
{
var node = new Node(data) {Next = Head?.Next};
if (Head != null) { Head.Previous = node;}
if (Tail == null) Tail = node;
Head = node;
}
public void Add(object data)
{
if (Head == null)
{
AddFirst(data);
}
else
{
var node = new Node(data) {Previous = Tail?.Previous};
if (Tail != null) Tail.Next = node;
node.Previous = Tail;
Tail = node;
}
}
private Node ItemAt(int index)
{
var item = Head;
while (index-- > 0) item = item.Next;
return item;
}
private void SetNewHead(int indexOfNewHead)
{
var newHead = ItemAt(indexOfNewHead);
var newTail = newHead.Previous;
var oldHead = Head;
var oldTail = Tail;
newHead.Previous = null;
newTail.Next = null;
oldTail.Next = oldHead;
oldHead.Previous = oldTail;
Head = newHead;
Tail = newTail;
}
/// <summary>
/// Rotates the Tail to the Head the specified number of times
/// </summary>
/// <param name="rotations">
/// The number of times to rotate the Tail to the Head
/// A negative number rotates the Head to the Tail
/// </param>
public void Rotate(int rotations)
{
var count = Count;
rotations = rotations % count;
if (rotations == 0) return;
// Find the index of the new head based on the number of rotations
// If rotations is positive, then the index is the count minus rotations
// If rotations is negative, then the index is 'rotations * -1' (or -rotations)
var newHeadIndex = rotations > 0 ? count - rotations : -rotations;
// Now that we know the index of the new head, we just set it as the head
SetNewHead(newHeadIndex);
}
public List<Node> ToList()
{
var nodes = new List<Node>();
for (var node = Head; node != null; node = node.Next)
{
nodes.Add(node);
}
return nodes;
}
public override string ToString()
{
return Count == 0 ? "{no items}" : "'" + string.Join("' <-> '", ToList()) + "'";
}
}
And here's a sample program that lets you enter some data and then rotate the list:
public static void Main(string[] args)
{
var linkedList = new LinkedList();
while (true)
{
var data = GetStringFromUser("Enter data to add, or 'exit' to stop: ");
if (data.Equals("exit", StringComparison.OrdinalIgnoreCase))
break;
linkedList.Add(new Node(data));
}
Console.WriteLine("\nLinked list items:");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(linkedList);
Console.ResetColor();
while (true)
{
var rotations = GetIntFromUser("\nEnter number of rotations, or 42 to stop: ");
if (rotations == 42) break;
linkedList.Rotate(rotations);
Console.WriteLine($"\nLinked list items after {rotations} rotations:");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(linkedList);
Console.ResetColor();
}
}
The code above uses the following helper methods:
public static string GetStringFromUser(string prompt)
{
Console.Write(prompt);
return Console.ReadLine();
}
public static int GetIntFromUser(string prompt, Func<double, bool> validator = null)
{
bool isValid = true;
int result;
do
{
if (!isValid)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Invalid input, please try again.");
Console.ResetColor();
}
else isValid = false;
Console.Write(prompt);
} while (!int.TryParse(Console.ReadLine(), out result) &&
(validator == null || !validator.Invoke(result)));
return result;
}
Sample Output
I tried to implement my linked list below, It just that when I used my linked list, it seems that it's inserting a null entry in the middle. Anyone could take a look? The problem could be in the add end method.
LinkedList<T>
public class LinkedList<T> : IEnumerable<T>
{
public Node<T> Head { get; set; }
public int Count { get; set; }
public LinkedList()
{
Head = new Node<T>();
}
public void AddStart(T data)
{
if (Head == null)
{
Head = new Node<T> {Value = data};
}
else
{
var newNode = new Node<T> {Value = data, Next = Head};
Head = newNode;
}
Count++;
}
public void AddEnd(T data)
{
var newNode = new Node<T> { Value = data, Next = null};
var current = Head;
if (Head == null)
{
Head = newNode;
}
else
{
while (current.Next != null)
{
current = current.Next;
}
current.Next = newNode;
}
}
public IEnumerator<T> GetEnumerator()
{
Node<T> current = Head;
while (current != null)
{
yield return current.Value;
current = current.Next;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Usage:
LinkedList<string> strings = new LinkedList<string>();
strings.AddStart("a");
strings.AddStart("b");
strings.AddStart("c");
strings.AddEnd("a");
strings.AddEnd("e");
strings.AddEnd("d");
Result: (Notice the null in the middle)
c
b
a
a
e
d
Usage:
LinkedList<string> strings = new LinkedList<string>();
strings.AddStart("a");
strings.AddStart("b");
strings.AddStart("c");
strings.AddEnd("a");
strings.AddEnd("e");
strings.AddEnd("d");
strings.AddStart("a");
strings.AddEnd("b");
strings.AddStart("a");
strings.AddStart("b");
strings.AddStart("c");
strings.AddEnd("a");
strings.AddEnd("e");
strings.AddEnd("d");
Result: (Notice the null in the middle)
c
b
a
a
c
b
a
a
e
d
b
a
e
d
You are creating an empty Node, when you initialize your LinkedList:
public LinkedList()
{
Head = new Node<T>();
}
At this point you essentially have a node without a value. This is displayed as an empty value.
Everytime you call AddStart, you insert items before hand. When calling AddEnd you insert items at the end. Since you call both methods equally, it appears that the initial node is in the middle.
You can resolve this by changing your constructor to this:
public LinkedList()
{
Head = null;
}
Or by removing the constructor alltogether. In both methods you are checking for a Head node with a value, so you do not need to initialize it without a value.
if (Head == null)
{
Head = new Node<T> {Value = data};
}
In your current state, you are checking if Head is null. Head is of Type Node, which, if it is a class, cannot be null, if you initialize it in your constrcutor (Head = new Node<T>(); //not null any longer). So you need to make up your mind on how you want to solve it.
Personally I'd just write a unit test to assert my logic and implementation is correct. If you assume that Head is null after initialisation, test for it:
[Fact]
public void AssertHeadIsNull()
{
var list = new LinkedList<int>();
Assert.Null(list.Head);
}
In your case, the test would have failed, and you could have backtracked the issue to your constructor.
I am trying to Remove my first value in my linked List y but i am not sure if my code is right my remove last is working fine but my removeFirst is not.
public class IntegerLinkedList
{
private class Node
{
public int value;
public Node next;
public Node(int v)
{
value = v;
next = null;
}
internal int removeLast()
{
int value;
if (next.next == null)
{
value = next.value;
next = null;
return value;
}
else
return next.removeLast();
}
internal int removeFirst()
{
int value;
if (next.next != null)
{
value = next.value;
next = null;
return value;
}
else
return next.removeFirst();
}
}
int count;
Node start;
here is my code for removeFirst
public int removeFirst()
{
int value;
if (start.next != null)
{
value = start.value;
}
else
value = start.removeFirst();
return value;
}
}
here is my link list
IntegerLinkedList myList = new IntegerLinkedList();
myList.addFirst(1);
myList.addFirst(2);
myList.addFirst(3);
myList.addFirst(4);
Console.WriteLine(" expect to 4 to be removed" + myList.removeFirst());
}
it displays
removed 4 but i am not sure if thats correct
This code:
internal int removeFirst()
{
int value;
if (next.next != null)
{
value = next.value;
next = null;
return value;
}
else
return next.removeFirst();
}
Is going to recursively traverse the list and cutoff the last element. It is effectively the same as removeLast.
Instead, you need to just do something like this:
Node currentStart = start;
start = start.next;
return currentStart.value;
The "start" Node object should no longer have any references pointing at it, so it will be GCd.
A quick note; you should likely remove "RemoveFirst" and "RemoveLast" from your Node class. Those are functions of the list; not nodes.
If you put all the methods in the list class (as you should!), addFirst (should be AddFirst) would be:
public void AddFirst(int item)
{
Node newNode = new Node();
newNode.value = item;
newNode.next = start;
start = newNode;
}
Your addLast requires iteration (or for you to track the "tail" node, your choice):
public void AddLast(int item)
{
Node newNode = new Node();
newNode.value = item;
Node tailNode = start;
while (tailNode.next != null)
tailNode = tailNode.next;
//In C++ you could cheat and do: while (tailNode = tailNode.next != null);
//Tail node is now at the end
tailNode.next = newNode;
}
I am trying to reverse a linked list. This is the code I have come up with:
public static void Reverse(ref Node root)
{
Node tmp = root;
Node nroot = null;
Node prev = null;
while (tmp != null)
{
//Make a new node and copy tmp
nroot = new Node();
nroot.data = tmp.data;
nroot.next = prev;
prev = nroot;
tmp = tmp.next;
}
root = nroot;
}
It is working well. Was wondering if it possible to avoid creating new node. Would like to have suggestions on this.
That question gets asked a lot. When I was asked it in my interviews many years ago, I reasoned as follows: a singly-linked list is essentially a stack. Reversing a linked list is therefore a trivial operation on stacks:
newList = emptyList;
while(!oldList.IsEmpty())
newList.Push(oldList.Pop());
Now all you have to do is implement IsEmpty and Push and Pop, which are one or two lines tops.
I wrote that out in about twenty seconds and the interviewer seemed somewhat perplexed at that point. I think he was expecting me to take about twenty minutes to do about twenty seconds work, which has always seemed odd to me.
Node p = root, n = null;
while (p != null) {
Node tmp = p.next;
p.next = n;
n = p;
p = tmp;
}
root = n;
Years ago I missed out on a hipster-L.A.-entertainment-company ASP.NET MVC developer position because I could not answer this question :( (It's a way to weed out non-computer-science majors.) So I am embarrassed to admit that it took me way too long to figure this out in LINQpad using the actual LinkedList<T>:
var linkedList = new LinkedList<int>(new[]{1,2,3,4,5,6,7,8,9,10});
linkedList.Dump("initial state");
var head = linkedList.First;
while (head.Next != null)
{
var next = head.Next;
linkedList.Remove(next);
linkedList.AddFirst(next.Value);
}
linkedList.Dump("final state");
The read-only LinkedListNode<T>.Next property is what makes LinkedList<T> so important here. (Non-comp-sci people are encouraged to study the history of Data Structures---we are supposed to ask the question, Where does the linked list come from---why does it exist?)
You don't need to make a copy. Some pseudo code:
prev = null;
current = head;
next = current->next;
(while next != null)
current->next=prev
prev=current
current=next
next=current->next
This performed pretty well on Leetcode.
public ListNode ReverseList(ListNode head) {
ListNode previous = null;
ListNode current = head;
while(current != null) {
ListNode nextTemp = current.next;
current.next = previous;
previous = current;
current = nextTemp;
}
return previous;
}
Why not just have the head point at the tail, the tail point at the head, and go through the list reversing the direction in which prev points?
If you're not using a head and a tail, just go through the list reversing the prev relationships, and then make head point at the one that had a null prev when you got to it.
public Node ReverseList(Node cur, Node prev)
{
if (cur == null) // if list is null
return cur;
Node n = cur.NextNode;
cur.NextNode = prev;
return (n == null) ? cur : ReverseList(n, cur);
}
Here a sample code to reverse a linked list.
using System;
class Program
{
static void Main(string[] args)
{
LinkItem item = generateLinkList(5);
printLinkList(item);
Console.WriteLine("Reversing the list ...");
LinkItem newItem = reverseLinkList(item);
printLinkList(newItem);
Console.ReadLine();
}
static public LinkItem generateLinkList(int total)
{
LinkItem item = new LinkItem();
for (int number = total; number >=1; number--)
{
item = new LinkItem
{
name = string.Format("I am the link item number {0}.", number),
next = (number == total) ? null : item
};
}
return item;
}
static public void printLinkList(LinkItem item)
{
while (item != null)
{
Console.WriteLine(item.name);
item = item.next;
}
}
static public LinkItem reverseLinkList(LinkItem item)
{
LinkItem newItem = new LinkItem
{
name = item.name,
next = null
};
while (item.next != null)
{
newItem = new LinkItem
{
name = item.next.name,
next = newItem
};
item = item.next;
}
return newItem;
}
}
class LinkItem
{
public string name;
public LinkItem next;
}
linked list reversal recursive
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ReverseLinkedList
{
class Program
{
static void Main(string[] args)
{
Node head = null;
LinkedList.Append(ref head, 25);
LinkedList.Append(ref head, 5);
LinkedList.Append(ref head, 18);
LinkedList.Append(ref head, 7);
Console.WriteLine("Linked list:");
LinkedList.Print(head);
Console.WriteLine();
Console.WriteLine("Reversed Linked list:");
LinkedList.Reverse(ref head);
LinkedList.Print(head);
Console.WriteLine();
Console.WriteLine("Reverse of Reversed Linked list:");
LinkedList.ReverseUsingRecursion(head);
head = LinkedList.newHead;
LinkedList.PrintRecursive(head);
}
public static class LinkedList
{
public static void Append(ref Node head, int data)
{
if (head != null)
{
Node current = head;
while (current.Next != null)
{
current = current.Next;
}
current.Next = new Node();
current.Next.Data = data;
}
else
{
head = new Node();
head.Data = data;
}
}
public static void Print(Node head)
{
if (head == null) return;
Node current = head;
do
{
Console.Write("{0} ", current.Data);
current = current.Next;
} while (current != null);
}
public static void PrintRecursive(Node head)
{
if (head == null)
{
Console.WriteLine();
return;
}
Console.Write("{0} ", head.Data);
PrintRecursive(head.Next);
}
public static void Reverse(ref Node head)
{
if (head == null) return;
Node prev = null, current = head, next = null;
while (current.Next != null)
{
next = current.Next;
current.Next = prev;
prev = current;
current = next;
}
current.Next = prev;
head = current;
}
public static Node newHead;
public static void ReverseUsingRecursion(Node head)
{
if (head == null) return;
if (head.Next == null)
{
newHead = head;
return;
}
ReverseUsingRecursion(head.Next);
head.Next.Next = head;
head.Next = null;
}
}
public class Node
{
public int Data = 0;
public Node Next = null;
}
}
}
Complexity O(n+m). Assuming head is the start node:
List<Node>Nodes = new List<Node>();
Node traverse= root;
while(traverse!=null)
{
Nodes.Add(traverse);
traverse = traverse.Next;
}
int i = Nodes.Count - 1;
root = Nodes[i];
for(; i>0; i--)
{
Nodes[i].Next = Nodes[i-1];
}
Nodes[0].Next=null;
In case you want a ready-made efficient implementation, I created an alternative to LinkedList that supports enumeration and reverse operations. https://github.com/NetFabric/NetFabric.DoubleLinkedList
public class Node<T>
{
public T Value { get; set; }
public Node<T> Next { get; set; }
}
public static Node<T> Reverse<T>(Node<T> head)
{
Node<T> tail = null;
while(head!=null)
{
var node = new Node<T> { Value = head.Value, Next = tail };
tail = node;
head = head.Next;
}
return tail;
}
The definition of ref is unnecessary because if you make the node as a reference type, it is OK to do:
public static void Reverse(Node root)
Also, the beauty of the interview question is less consumption of memory and in place reversal. Maybe a recursive way of doing it is also asked.
class ListNode
{
public object Data { get; private set; }
public ListNode Next { get; set; }
public ListNode(object Element)
{
Data = Element;
}
public ListNode(object Element, ListNode NextNode)
{
Data = Element;
Next = NextNode;
}
public ListNode()
{
}
}
class LinkedList
{
ListNode first;
ListNode last;
public LinkedList()
{
first = null;
last = null;
}
public ListNode Find(object After)
{
ListNode current = new ListNode();
current= first;
while (current.Data != After)
current = current.Next;
return current;
}
public void Add(object newItem, object After)
{
ListNode current=new ListNode();
ListNode newNode=new ListNode();
current = Find(After);
newNode.Next = current.Next;
current.Next = newNode;
}
public void InsertAtFront(object Element)
{
if (IsEmpty())
{
first = last = new ListNode(Element);
}
else
{
first = new ListNode(Element,first);
}
}
bool IsEmpty()
{
return first == null;
}
public void Display()
{
ListNode current = first;
while (current!=null)
{
Console.WriteLine(current.Data);
current = current.Next;
}
}
}
I implement Find method for Add After specific element, but when I debug it showing me the object reference not set to an instance of an object exception. Please point out my mistake in Find method or with Add After method. thanks
current= first;
while (current.Data != After)
can result in a potential null reference issue. first can still be set to null from the constructor initialisation which would mean that current = null, which'd then result in null.Data which would throw a null reference exception.
This would fix the null reference issue in Find()
while (current != null && current.Data != After)
Fixing this would result in null being returned which would still result in issues in Add
current = Find(After);
newNode.Next = current.Next;
current.Next = newNode;
In this context, LinkedList is first initialised, current = Find(After) would mean current = null, causing another null reference exceptions on the next two lines.
public void Add(object newItem, object After)
{
if (IsEmpty())
{
InsertAtFront(newItem);
return;
}
ListNode newNode = new ListNode();
ListNode current = Find(After);
newNode.Next = current.Next;
current.Next = newNode;
}
This will fix both the Add and the Find methods to be usable in the form of:
LinkedList list = new LinkedList();
list.InsertAtFront("test");
list.Find(list.first.Data);
list.Add("test2", ll.first.Data);
This will make it workable, but I would however highly recommend reading into the implementation of linked lists or using one of the system collections as this implementation has quite a few potential issues.
Problem is here
while (current.Data != After)
current = current.Next;
When there is no After in your list you will eventually get current.Next equal to null
You need to check if current.Next is not null
while (current.Next != null && current.Data != After)
current = current.Next;
you should also fix your add logic (if you want to add elements into empty list)
public void Add(object newItem, object After)
{
if(IsEmpty())
{
InsertAtFront(newItem);
return;
}
ListNode newNode=new ListNode();
newNode.Data = newItem;
ListNode current = Find(After);
newNode.Next = current.Next;
current.Next = newNode;
}