/// <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--;
        }
Exemple #4
0
        /// <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);
        }
Exemple #7
0
        /// <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);
        }
Exemple #8
0
        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--;
        }
Exemple #10
0
        /// <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++;
        }
Exemple #11
0
 /// <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;
 }