/// <summary> /// Replaces the Head of the list with the new value. /// </summary> /// <param name="data"> Value for the new Head of the list.</param> /// <returns>The new Head node.</returns> public DoublyLinkedListNode <T> AddHead(T data) { var node = new DoublyLinkedListNode <T>(data); if (Head is null) { Head = node; Tail = node; Count = 1; return(node); } Head.Previous = node; node.Next = Head; Head = node; Count++; return(node); }
/// <summary> /// Removes the last node in the list. /// </summary> public void Remove() { if (Tail is null) { throw new InvalidOperationException("Cannot prune empty list"); } Tail = Tail.Previous; if (Tail is null) { Head = null; Count = 0; return; } Tail.Next = null; Count--; }
/// <summary> /// Removes the Head and replaces it with the second node in the list. /// </summary> public void RemoveHead() { if (Head is null) { throw new InvalidOperationException(); } Head = Head.Next; if (Head is null) { Tail = null; Count = 0; return; } Head.Previous = null; Count--; }
/// <summary> /// Removes the first item in the list /// </summary> public void RemoveFirst() { if (Count != 0) { // Remove the head node _head = _head.Next; // Decrement the count Count--; if (Count == 0) { // List is now empty, null the tail _tail = null; } else { // null the heads previous property _head.Previous = null; } } }
/// <summary> /// Reverses the list. Because of how doubly linked list are structured this is not a complex action. /// </summary> public void Reverse() { DoublyLinkedListNode <T>?current = Head; DoublyLinkedListNode <T>?temp = null; while (current != 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 != null) { Head = temp.Previous; } }
/// <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 != null) { existingNode.Next.Previous = node; } Count++; return(node); }
/// <summary> /// Remove the first occurance of an element from the list. /// </summary> /// <param name="item"></param> /// <returns></returns> public bool Remove(T item) { DoublyLinkedListNode <T> previous = null; DoublyLinkedListNode <T> current = Head; while (current != null) { if (current.Value.Equals(item)) { // A node in the middle or end if (previous != null) { previous.Next = current.Next; if (current.Next == null) { Tail = previous; } else { current.Next.Previous = previous; } Count--; } else { RemoveFirst(); } return(true); } previous = current; current = current.Next; } return(false); }
public void RemoveLast() { if (Count != 0) { if (Count == 1) { // Removing only node in list // null the head and tail _head = null; _tail = null; } else { // Set the preceding node as the tail _tail = _tail.Previous; // Set the tail's Next property to null _tail.Next = null; } // Decrement the count Count--; } }
/// <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> /// Adds an item to the end of the list /// </summary> /// <param name="item">The item to add to the end of the list</param> public void AddLast(T item) { // Create a new node DoublyLinkedListNode <T> node = new DoublyLinkedListNode <T>(item); if (Count == 0) { // The list is empty, the new node will be head and the tail _head = node; } else { // Set the current tails Next property to the new node _tail.Next = node; // Set the nodes Previous property to the current tail node.Previous = _tail; } // Make the new node the tail _tail = node; // Increment the Count Count++; }
/// <summary> /// Removes all items from the list /// </summary> public void Clear() { _head = null; _tail = null; Count = 0; }
/// <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; }