public int CompareTo(DLinkedListNode <T> other)
        {
            if (other == null)
            {
                return(-1);
            }

            return(this.Data.CompareTo(other.Data));
        }
            public bool MovePrevious()
            {
                if (_current.Previous != null)
                {
                    _current = _current.Previous;
                }
                else
                {
                    return(false);
                }

                return(true);
            }
            public bool MoveNext()
            {
                if (_current.Next != null)
                {
                    _current = _current.Next;
                }
                else
                {
                    return(false);
                }

                return(true);
            }
        /// <summary>
        /// Returns a number of elements as specified by countOfElements, starting from the specified index.
        /// </summary>
        /// <param name="index">Starting index.</param>
        /// <param name="countOfElements">The number of elements to return.</param>
        /// <returns>Doubly-Linked List of elements</returns>
        public virtual DLinkedList <T> GetRange(int index, int countOfElements)
        {
            DLinkedListNode <T> currentNode = null;
            DLinkedList <T>     newList     = new DLinkedList <T>();

            // Handle Index out of Bound errors
            if (Count == 0)
            {
                return(newList);
            }

            if (index < 0 || index > Count)
            {
                throw new IndexOutOfRangeException();
            }

            // Decide from which reference to traverse the list, and then move the currentNode reference to the index
            // If index > half then traverse it from the end (_lastNode reference)
            // Otherwise, traverse it from the beginning (_firstNode refrence)
            if (index > (Count / 2))
            {
                currentNode = this._lastNode;
                for (int i = (Count - 1); i > index; --i)
                {
                    currentNode = currentNode.Previous;
                }
            }
            else
            {
                currentNode = this._firstNode;
                for (int i = 0; i < index; ++i)
                {
                    currentNode = currentNode.Next;
                }
            }

            // Append the elements to the new list using the currentNode reference
            while (currentNode != null && newList.Count <= countOfElements)
            {
                newList.Append(currentNode.Data);
                currentNode = currentNode.Next;
            }

            return(newList);
        }
        /// <summary>
        /// Append the specified dataItem at the end of the list.
        /// </summary>
        /// <param name="dataItem">Data item.</param>
        public virtual void Append(T dataItem)
        {
            DLinkedListNode <T> newNode = new DLinkedListNode <T>(dataItem);

            if (_firstNode == null)
            {
                _firstNode = _lastNode = newNode;
            }
            else
            {
                var currentNode = _lastNode;
                currentNode.Next = newNode;
                newNode.Previous = currentNode;
                _lastNode        = newNode;
            }

            // Increment the count.
            _count++;
        }
        /// <summary>
        /// Sets the value of the element at the specified index
        /// </summary>
        /// <param name="index">Index of element to update.</param>
        /// <returns>Element</returns>
        protected virtual void _setElementAt(int index, T value)
        {
            if (IsEmpty() || index < 0 || index >= Count)
            {
                throw new IndexOutOfRangeException("List is empty.");
            }

            if (index == 0)
            {
                _firstNode.Data = value;
            }
            else if (index == (Count - 1))
            {
                _lastNode.Data = value;
            }
            else
            {
                DLinkedListNode <T> currentNode = null;

                // Decide from which reference to traverse the list, and then move the currentNode reference to the index
                // If index > half then traverse it from the end (_lastNode reference)
                // Otherwise, traverse it from the beginning (_firstNode refrence)
                if (index > (Count / 2))
                {
                    currentNode = this._lastNode;
                    for (int i = (Count - 1); i > index; --i)
                    {
                        currentNode = currentNode.Previous;
                    }
                }
                else
                {
                    currentNode = this._firstNode;
                    for (int i = 0; i < index; ++i)
                    {
                        currentNode = currentNode.Next;
                    }
                }

                currentNode.Data = value;
            }
        }
        /// <summary>
        /// Inserts the dataItem at the specified index.
        /// </summary>
        /// <param name="dataItem">Data item.</param>
        /// <param name="index">Index.</param>
        public virtual void InsertAt(T dataItem, int index)
        {
            if (index < 0 || index > Count)
            {
                throw new IndexOutOfRangeException();
            }

            if (index == 0)
            {
                Prepend(dataItem);
            }
            else if (index == Count)
            {
                Append(dataItem);
            }
            else
            {
                DLinkedListNode <T> currentNode = null;
                DLinkedListNode <T> newNode     = new DLinkedListNode <T>(dataItem);

                currentNode = this._firstNode;
                for (int i = 0; i < index - 1; ++i)
                {
                    currentNode = currentNode.Next;
                }

                var oldNext = currentNode.Next;

                if (oldNext != null)
                {
                    currentNode.Next.Previous = newNode;
                }

                newNode.Next     = oldNext;
                currentNode.Next = newNode;
                newNode.Previous = currentNode;

                // Increment the count
                _count++;
            }
        }
 public void Dispose()
 {
     _current          = null;
     _doublyLinkedList = null;
 }
 public void Reset()
 {
     _current = _doublyLinkedList.Head;
 }
 public DLinkedListEnumerator(DLinkedList <T> list)
 {
     this._current          = list.Head;
     this._doublyLinkedList = list;
 }
        /// <summary>
        /// Remove the specified dataItem.
        /// </summary>
        public virtual void RemoveFirstMatch(Predicate <T> match)
        {
            // Handle index out of bound errors
            if (IsEmpty())
            {
                throw new IndexOutOfRangeException();
            }

            if (match(_firstNode.Data))
            {
                _firstNode = _firstNode.Next;

                if (_firstNode != null)
                {
                    _firstNode.Previous = null;
                }
            }
            else if (match(_lastNode.Data))
            {
                _lastNode = _lastNode.Previous;

                if (_lastNode != null)
                {
                    _lastNode.Next = null;
                }
            }
            else
            {
                // Remove
                var currentNode = _firstNode;

                // Get currentNode to reference the element at the index.
                while (currentNode.Next != null)
                {
                    if (match(currentNode.Data))
                    {
                        break;
                    }

                    currentNode = currentNode.Next;
                }//end-while

                // If we reached the last node and item was not found
                // Throw exception
                if (!match(currentNode.Data))
                {
                    throw new Exception("Item was not found!");
                }

                // Remove element
                DLinkedListNode <T> newPrevious = currentNode.Previous;
                DLinkedListNode <T> newNext     = currentNode.Next;

                if (newPrevious != null)
                {
                    newPrevious.Next = newNext;
                }

                if (newNext != null)
                {
                    newNext.Previous = newPrevious;
                }

                currentNode = newPrevious;
            }

            // Decrement count.
            _count--;
        }
 public DLinkedListNode(T dataItem, DLinkedListNode <T> next, DLinkedListNode <T> previous)
 {
     Data     = dataItem;
     Next     = next;
     Previous = previous;
 }