170 lines
4.9 KiB
C#
170 lines
4.9 KiB
C#
namespace C_.Datastructures.LinkedList
|
|
{
|
|
public class LinkedList<T>
|
|
{
|
|
internal LinkedListNode<T>? Head { get; set; } = default;
|
|
private int Count { get; set; } = 0;
|
|
|
|
public static LinkedList<T> Create()
|
|
{
|
|
//Create a new empty list
|
|
return new LinkedList<T>();
|
|
}
|
|
|
|
public static LinkedList<T> Create(T value)
|
|
{
|
|
//Create a new Class with a single item
|
|
return new LinkedList<T>()
|
|
{
|
|
Head = LinkedListNode<T>.Create(value, null),
|
|
Count = 1
|
|
};
|
|
}
|
|
|
|
public static LinkedList<T> Create(LinkedList<T> list1, LinkedList<T> list2)
|
|
{
|
|
//Append a previous list to a new List
|
|
LinkedList<T> list;
|
|
|
|
list = list1;
|
|
if (list == null || list.Count == 0) return list2;
|
|
|
|
//Find end of list and append fist item of next list
|
|
if (list2 == null || list.Count == 0) return list;
|
|
|
|
LinkedListNode<T>? end = list.Traverse();
|
|
end!.Next = list2!.Head;
|
|
list.Count += list2!.Count;
|
|
|
|
return list;
|
|
}
|
|
|
|
public T? this[int i]
|
|
{
|
|
get
|
|
{
|
|
//Check Range
|
|
if (i >= Count || i < 0) throw new System.Exception("Error! Index out of Bounds");
|
|
|
|
//Return Value
|
|
LinkedListNode<T>? node = Traverse(i);
|
|
if (node != null) return node.Value;
|
|
return default;
|
|
}
|
|
set
|
|
{
|
|
//Check Range
|
|
if (i >= Count || i < 0) throw new System.Exception("Error! Index out of Bounds");
|
|
|
|
//Change Value
|
|
LinkedListNode<T>? node = Traverse(i);
|
|
node!.Value = value;
|
|
}
|
|
}
|
|
|
|
public void Append(T value)
|
|
{
|
|
//Create new node
|
|
Count++;
|
|
LinkedListNode<T> newItem = LinkedListNode<T>.Create(value, default);
|
|
|
|
//Set head to new item if list is empty
|
|
if (Head == null)
|
|
{
|
|
Head = newItem;
|
|
return;
|
|
}
|
|
|
|
//Find last item in list
|
|
LinkedListNode<T>? end = Head;
|
|
if (end != null)
|
|
{
|
|
end = Traverse();
|
|
}
|
|
|
|
//Append item to end
|
|
end!.Next = newItem;
|
|
}
|
|
|
|
public void Insert(int index, T value)
|
|
{
|
|
Count++;
|
|
if (index > Count || index < 0) throw new System.Exception("Error! Index outside of Bounds");
|
|
|
|
//Set head to new item if list is empty
|
|
if (index == 0 || Head == null)
|
|
{
|
|
Head = LinkedListNode<T>.Create(value, Head);
|
|
return;
|
|
}
|
|
|
|
//Fetch point in list at which item will be added
|
|
LinkedListNode<T>? node = Traverse(index - 1);
|
|
|
|
node!.Next = LinkedListNode<T>.Create(value, node!.Next);
|
|
}
|
|
|
|
public void Delete(int index)
|
|
{
|
|
Count--;
|
|
if (index > Count || index < 0) throw new System.Exception("Error! Index outside of Bounds");
|
|
|
|
//Check if we are trying to reference the first item
|
|
if (index == 0 && Head != default)
|
|
{
|
|
Head = Head!.Next;
|
|
return;
|
|
}
|
|
|
|
//Find node before the one we are trying to delete and then remove / relink
|
|
LinkedListNode<T>? node = Traverse(index - 1);
|
|
|
|
node!.Next = node.Next!.Next;
|
|
}
|
|
|
|
private LinkedListNode<T>? Traverse()
|
|
{
|
|
//Start at Head of list
|
|
LinkedListNode<T>? node = Head;
|
|
if (node != null)
|
|
{
|
|
//continue to end of list
|
|
while (node!.Next != default)
|
|
{
|
|
node = (LinkedListNode<T>)node.Next;
|
|
}
|
|
}
|
|
return node;
|
|
}
|
|
|
|
//private static LinkedListNode<T>? Traverse(LinkedListNode<T> start){
|
|
// //Start at given point in list
|
|
// LinkedListNode<T>? node = start;
|
|
// if (node != null)
|
|
// {
|
|
// //Continue to end of list
|
|
// while (node!.Next != default)
|
|
// {
|
|
// node = (LinkedListNode<T>)node.Next;
|
|
// }
|
|
// }
|
|
// return node;
|
|
//}
|
|
|
|
private LinkedListNode<T>? Traverse(int i)
|
|
{
|
|
//Start at given point in list
|
|
LinkedListNode<T>? node = Head;
|
|
if (node != null || i == 0)
|
|
{
|
|
//Continue to end of list
|
|
for (int j = 0; j < i; j++)
|
|
{
|
|
if (node!.Next == null) return null;
|
|
node = (LinkedListNode<T>)node.Next;
|
|
}
|
|
}
|
|
return node;
|
|
}
|
|
}
|
|
} |