Updated Repo Layout
This commit is contained in:
211
C#/Datastructures/DoublyLinkedList/DoublyLinkedList.cs
Normal file
211
C#/Datastructures/DoublyLinkedList/DoublyLinkedList.cs
Normal file
@ -0,0 +1,211 @@
|
||||
namespace C_.Datastructures.DoublyLinkedList
|
||||
{
|
||||
public class DoublyLinkedList<T>
|
||||
{
|
||||
internal DoublyLinkedListNode<T>? Head { get; set; } = default;
|
||||
internal DoublyLinkedListNode<T>? Tail { get; set; } = default;
|
||||
private int Count { get; set; } = 0;
|
||||
|
||||
public static DoublyLinkedList<T> Create()
|
||||
{
|
||||
//Create a new empty list
|
||||
return new DoublyLinkedList<T>();
|
||||
}
|
||||
|
||||
public static DoublyLinkedList<T> Create(T value)
|
||||
{
|
||||
//Create a new Class with a single item
|
||||
return new DoublyLinkedList<T>()
|
||||
{
|
||||
Head = DoublyLinkedListNode<T>.Create(value, default, default),
|
||||
Count = 1
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static DoublyLinkedList<T> Create(DoublyLinkedList<T> list1, DoublyLinkedList<T> list2)
|
||||
{
|
||||
//Create a new list from 2 separate lists
|
||||
|
||||
DoublyLinkedList<T> list;
|
||||
|
||||
list = list1;
|
||||
if (list == default || list.Count == 0) return list2;
|
||||
|
||||
//Find end of list and append fist item of next list
|
||||
if (list2 == default || list.Count == 0) return list;
|
||||
|
||||
DoublyLinkedListNode<T>? end = list.Traverse();
|
||||
|
||||
//Connect up pointers at ajoining section
|
||||
end!.Next = list2!.Head;
|
||||
end!.Next!.Prev = end;
|
||||
end = list2.Tail;
|
||||
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
|
||||
DoublyLinkedListNode<T>? node = Traverse(i);
|
||||
if (node != default) return node.Value;
|
||||
return default;
|
||||
}
|
||||
set
|
||||
{
|
||||
//Check Range
|
||||
if (i >= Count || i < 0) throw new System.Exception("Error! Index out of Bounds");
|
||||
|
||||
//Change Value
|
||||
DoublyLinkedListNode<T>? node = Traverse(i);
|
||||
node!.Value = value;
|
||||
}
|
||||
}
|
||||
public void Append(T value)
|
||||
{
|
||||
Count++;
|
||||
|
||||
//Set head to new item if list is empty
|
||||
if (Head == null)
|
||||
{//Append item to front of list (End as well)
|
||||
Head = DoublyLinkedListNode<T>.Create(value, default, default);
|
||||
Tail = Head;
|
||||
return;
|
||||
}
|
||||
|
||||
//Append item to the end of the list
|
||||
Tail!.Next = DoublyLinkedListNode<T>.Create(value, default, Tail);
|
||||
Tail = Tail.Next;
|
||||
}
|
||||
|
||||
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 = DoublyLinkedListNode<T>.Create(value, Head, default);
|
||||
Tail = Head;
|
||||
return;
|
||||
}
|
||||
|
||||
//Set tail to new item if index is the end
|
||||
if (index == Count - 1)
|
||||
{
|
||||
//Decrement count as it will be be re-incremented once appended
|
||||
Count--;
|
||||
Append(value);
|
||||
return;
|
||||
}
|
||||
|
||||
//Fetch point in list and add new item
|
||||
DoublyLinkedListNode<T>? node = Traverse(index - 1);
|
||||
node!.Next = DoublyLinkedListNode<T>.Create(value, node.Next, node);
|
||||
|
||||
//Create backlink in the list
|
||||
if (node.Next.Next != default)
|
||||
node.Next.Next.Prev = 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;
|
||||
if (Head != default)
|
||||
Head.Prev = default;
|
||||
return;
|
||||
}
|
||||
|
||||
//Set tail to new item if index is the end
|
||||
if (index == Count && Tail != default)
|
||||
{
|
||||
Tail = Tail!.Prev;
|
||||
|
||||
if (Tail != default)
|
||||
Tail.Next = default;
|
||||
return;
|
||||
}
|
||||
|
||||
DoublyLinkedListNode<T>? node = Traverse(index - 1);
|
||||
|
||||
node!.Next = node.Next!.Next;
|
||||
|
||||
//Connect item after to the the item before the node we are deleting
|
||||
if (node.Next != default)
|
||||
{
|
||||
node.Next.Prev = node;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private DoublyLinkedListNode<T>? Traverse()
|
||||
{
|
||||
//Return the final item in the list
|
||||
return Tail;
|
||||
}
|
||||
|
||||
private DoublyLinkedListNode<T>? Traverse(int i)
|
||||
{
|
||||
//Determine whether to start at the start or end of the list
|
||||
int direction = 1;
|
||||
DoublyLinkedListNode<T>? node = Head;
|
||||
|
||||
if (i > (Count / 2))
|
||||
{
|
||||
//reverse direction of search
|
||||
direction = -1;
|
||||
node = Tail;
|
||||
//i becomes the amount of hops left to reach the item
|
||||
i = Count - i - 1;
|
||||
}
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
|
||||
//continue to given point in the list ('i' hops)
|
||||
for (int x = 0; x < i; x++)
|
||||
{
|
||||
if (direction == 1)
|
||||
{//Going forwards
|
||||
node = node!.Next;
|
||||
}
|
||||
else
|
||||
{
|
||||
node = node!.Prev;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
private DoublyLinkedListNode<T>? Next(DoublyLinkedListNode<T> current)
|
||||
{
|
||||
if (current != default)
|
||||
return current.Next;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private DoublyLinkedListNode<T>? Prev(DoublyLinkedListNode<T> current)
|
||||
{
|
||||
if (current != default)
|
||||
return current.Prev;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
19
C#/Datastructures/DoublyLinkedList/DoublyLinkedListNode.cs
Normal file
19
C#/Datastructures/DoublyLinkedList/DoublyLinkedListNode.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using C_.Datastructures.Generic;
|
||||
|
||||
namespace C_.Datastructures.DoublyLinkedList
|
||||
{
|
||||
internal class DoublyLinkedListNode<T> : Node<T, DoublyLinkedListNode<T>>
|
||||
{//Inherits from Node
|
||||
public DoublyLinkedListNode<T>? Prev { get; set; } = default;
|
||||
|
||||
public static DoublyLinkedListNode<T> Create(T? value, DoublyLinkedListNode<T>? next, DoublyLinkedListNode<T>? prev)
|
||||
{
|
||||
return new DoublyLinkedListNode<T>
|
||||
{
|
||||
Value = value,
|
||||
Next = next,
|
||||
Prev = prev
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user