I have implemented a LinkedList
in C#. What would you change/make better? What naming conventions are misused? What would you add? Some of my ideas are to make it thread-safe.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestIt.DataStructures
{
public class MyLinkedList<T> : IList<T>
{
private int size;
private MyLinkedListNode<T> head;
public long Size()
{
return size;
}
public void Add(T nodeValue)
{
Add(new MyLinkedListNode<T>(nodeValue));
}
public void Add(MyLinkedListNode<T> newItem)
{
if (size == 0)
{
head = newItem;
}
else
{
var last = head;
while (last.Next != null) { last = last.Next; }
last.Next = newItem;
newItem.Prev = last;
}
size++;
}
public MyLinkedListNode<T> Get(long index)
{
if (index > size)
{
throw new IndexOutOfRangeException(String.Format("List size is {0} but the index {1}", size, index));
}
long c = 0;
var curr = head;
while (c != index) { curr = curr.Next; c++; }
return curr;
}
public bool Remove(long index)
{
if (index > size)
{
throw new IndexOutOfRangeException(String.Format("List size is {0} but the index {1}", size, index));
}
if (size == 0) return false;
long c = 0;
var curr = head;
while (curr.Next != null && c < index) { curr = curr.Next; c++; }
if (curr.Prev == null && curr.Next == null)
{
curr = null;
head = null;
}
else if (curr.Prev == null) { curr.Next.Prev = null; head = curr.Next; curr = null; }
else if (curr.Next == null) { curr.Prev.Next = null; curr = null; }
else
{
curr.Prev.Next = curr.Next;
curr.Next.Prev = curr.Prev;
curr = null;
}
size--;
return true;
}
public bool Remove(MyLinkedListNode<T> node)
{
if (size == 0)
{
return false;
}
var curr = head;
while (curr != null && curr != node) { curr = curr.Next; }
if (curr == null) { return false; }
curr.Next.Prev = curr.Prev;
curr.Prev.Next = curr.Next;
curr = null;
size--;
return true;
}
public int IndexOf(T item)
{
if (item == null)
{
return -1;
}
int index = 0;
var curr = head;
while (curr != null)
{
if (curr.Value.Equals(item))
{
return index;
}
curr = curr.Next;
index++;
}
return -1;
}
public void Insert(int index, T item)
{
if (index > size + 1)
{
throw new Exception("Index if out of range of the linked list");
}
var curr = head;
var i = 0;
if (index == i)
{
var newNode = new MyLinkedListNode<T>(item);
newNode.Next = curr;
head = newNode;
size++;
return;
}
curr = curr.Next;
i++;
while (curr != null)
{
if (i == index)
{
var newNode = new MyLinkedListNode<T>(item);
newNode.Next = curr.Next;
curr.Next = newNode;
size++;
return;
}
curr = curr.Next;
i++;
}
}
public void RemoveAt(int index)
{
Remove(index);
}
public T this[int index]
{
get
{
if (size < index - 1)
{
throw new IndexOutOfRangeException();
}
var curr = head;
int i = 0;
while (curr != null)
{
if (i == index)
{
return curr.Value;
}
curr = curr.Next;
i++;
}
return default(T);
}
set
{
if (size < index - 1)
{
var curr = head;
int i = 0;
while (curr != null)
{
if (i == index)
{
curr.Value = value;
return;
}
curr = curr.Next;
i++;
}
}
}
}
public void Clear()
{
size = 0;
head = null;
}
public bool Contains(T item)
{
if (size == 0)
{
return false;
}
var curr = head;
while (curr != null)
{
if (curr.Value.Equals(item))
{
return true;
}
curr = curr.Next;
}
return false;
}
public void CopyTo(T[] array, int arrayIndex)
{
if (size == 0)
{
return;
}
var curr = head;
while (curr != null)
{
array[arrayIndex] = curr.Value;
curr = curr.Next;
arrayIndex++;
}
}
public int Count
{
get { return (int)size; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(T item)
{
return Remove(new MyLinkedListNode<T>(item));
}
public IEnumerator<T> GetEnumerator()
{
var curr = head;
while (curr != null)
{
yield return curr.Value;
curr = curr.Next;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class MyLinkedListNode<T> : IComparable<T>
{
public T Value { get; set; }
public MyLinkedListNode<T> Next { get; set; }
public MyLinkedListNode<T> Prev { get; set; }
public MyLinkedListNode(T value)
{
this.Value = value;
}
public int CompareTo(T other)
{
throw new NotImplementedException();
}
}
}