using System; using System.Linq; using System.Text; using System.Threading.Tasks; using C_.Datastructures.Nodes; namespace C_.Datastructures { internal class DoublyLinkedList { internal DoublyLinkedListNode? Head { get; set; } = default; internal DoublyLinkedListNode? Tail { get; set; } = default; private int Count { get; set; } = 0; public static DoublyLinkedList Create() { //Create a new empty list return new DoublyLinkedList(); } public static DoublyLinkedList Create(T value) { //Create a new Class with a single item return new DoublyLinkedList() { Head = DoublyLinkedListNode.Create(value, null, null), Count = 1 }; } public static DoublyLinkedList Create(DoublyLinkedList list1, DoublyLinkedList list2) { //Create a new list from 2 separate lists DoublyLinkedList 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; DoublyLinkedListNode? 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? 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 DoublyLinkedListNode? node = Traverse(i); node!.Value = value; } } public void Add(T value) { Count++; if (Tail != null && Count > 0) { Tail.Next = new DoublyLinkedListNode { Value = value, Next = null, Prev = Tail }; Tail = Tail.Next; return; } Head = new DoublyLinkedListNode { Value = value, Next = null, Prev = null }; Tail = Head; } public bool Delete(int index){ DoublyLinkedListNode? node = Traverse(index); if (node == default) return false; if(node.Prev != default){ //connect item beofre to item after node we are deleting node.Prev.Next = node.Next; } //Connect item after to the the item before the node we are deleting if (node.Next != default) { node.Next.Prev = node.Prev; } Count--; return true; } private DoublyLinkedListNode? Traverse() { //Return the final item in the list return Tail; } private DoublyLinkedListNode? Traverse(int i) { //Determine whether to start at the start or end of the list int direction = 1; DoublyLinkedListNode? 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? Next(DoublyLinkedListNode current) { if (current != null) return current.Next; return null; } private DoublyLinkedListNode? Prev(DoublyLinkedListNode current) { if (current != null) return current.Prev; return null; } } }