/// <summary> /// Adds a new value after an existing node. /// </summary> /// <param name="data"> New value to be added to the list.</param> /// <param name="existingNode"> An existing node in the list.</param> /// <returns>The new node created based on the new value.</returns> public DoublyLinkedListNode <T> AddAfter(T data, DoublyLinkedListNode <T> existingNode) { if (existingNode == Tail) { return(Add(data)); } var node = new DoublyLinkedListNode <T>(data); node.Next = existingNode.Next; node.Previous = existingNode; existingNode.Next = node; if (existingNode.Next is not null) { existingNode.Next.Previous = node; } Count++; return(node); }
/// <summary> /// Reverses the list. Because of how doubly linked list are structured this is not a complex action. /// </summary> public void Reverse() { var current = Head; DoublyLinkedListNode <T>?temp = null; while (current is not null) { temp = current.Previous; current.Previous = current.Next; current.Next = temp; current = current.Previous; } Tail = Head; // temp can be null on empty list if (temp is not null) { Head = temp.Previous; } }
/// <summary> /// Removes specific node. /// </summary> /// <param name="node"> Node to be removed.</param> public void RemoveNode(DoublyLinkedListNode <T> node) { if (node == Head) { RemoveHead(); return; } if (node == Tail) { Remove(); return; } if (node.Previous is null || node.Next is null) { throw new ArgumentException($"{nameof(node)} cannot have Previous or Next null if it's an internal node"); } node.Previous.Next = node.Next; node.Next.Previous = node.Previous; Count--; }
/// <summary> /// Initializes a new instance of the <see cref="DoublyLinkedList{T}" /> class. /// </summary> /// <param name="data"> Data of the original head of the list.</param> public DoublyLinkedList(T data) { Head = new DoublyLinkedListNode <T>(data); Tail = Head; Count = 1; }