コード例 #1
0
        /// <summary>
        /// Create or get an element in the vector.
        /// </summary>
        /// <param name="index">Index in the vector</param>
        /// <returns>The vector element at the specified index</returns>
        public VectorElement <T> GetElement(int index)
        {
            if (index < 0)
            {
                throw new ArgumentException("Invalid index {0}".FormatString(index));
            }
            if (index == 0)
            {
                return(_trashCan);
            }

            // Expand the vector if it is necessary
            if (index > Length)
            {
                Length = index;
            }

            // Find the element
            SparseVectorElement element = _firstInVector, lastElement = null;

            while (element != null)
            {
                if (element.Index > index)
                {
                    break;
                }
                if (element.Index == index)
                {
                    return(element);
                }
                lastElement = element;
                element     = element.NextInVector;
            }

            // Create a new element
            var result = new SparseVectorElement(index);

            // Update links for last element
            if (lastElement == null)
            {
                _firstInVector = result;
            }
            else
            {
                lastElement.NextInVector = result;
            }
            result.PreviousInVector = lastElement;

            // Update links for next element
            if (element == null)
            {
                _lastInVector = result;
            }
            else
            {
                element.PreviousInVector = result;
            }
            result.NextInVector = element;
            return(result);
        }
コード例 #2
0
        /// <summary>
        /// Swap two elements.
        /// </summary>
        /// <param name="index1">The index of the first element.</param>
        /// <param name="index2">The index of the second element.</param>
        public void Swap(int index1, int index2)
        {
            if (index1 < 0 || index2 < 0)
            {
                throw new SparseException("Invalid indices {0} and {1}".FormatString(index1, index2));
            }
            if (index1 == index2)
            {
                return;
            }
            if (index2 < index1)
            {
                var tmp = index1;
                index1 = index2;
                index2 = tmp;
            }

            // Get the two elements
            SparseVectorElement first = null, second = null;

            // Find first element
            var element = _firstInVector;

            while (element != null)
            {
                if (element.Index == index1)
                {
                    first = element;
                }
                if (element.Index > index1)
                {
                    break;
                }
                element = element.NextInVector;
            }

            // Find second element
            while (element != null)
            {
                if (element.Index == index2)
                {
                    second = element;
                }
                if (element.Index > index2)
                {
                    break;
                }
                element = element.NextInVector;
            }

            // Swap these elements
            Swap(first, second, index1, index2);
        }
コード例 #3
0
 /// <summary>
 /// Remove an element.
 /// </summary>
 /// <param name="element">Element to be removed.</param>
 private void Remove(SparseVectorElement element)
 {
     // Update surrounding links
     if (element.PreviousInVector == null)
     {
         _firstInVector = element.NextInVector;
     }
     else
     {
         element.PreviousInVector.NextInVector = element.NextInVector;
     }
     if (element.NextInVector == null)
     {
         _lastInVector = element.PreviousInVector;
     }
     else
     {
         element.NextInVector.PreviousInVector = element.PreviousInVector;
     }
 }
コード例 #4
0
        /// <summary>
        /// Swaps the specified elements.
        /// </summary>
        /// <param name="first">The first element.</param>
        /// <param name="second">The second element.</param>
        /// <param name="index1">The index of the first element.</param>
        /// <param name="index2">The index of the second element.</param>
        private void Swap(SparseVectorElement first, SparseVectorElement second, int index1, int index2)
        {
            // Nothing to do
            if (first == null && second == null)
            {
                return;
            }

            // Swap the elements
            if (first == null)
            {
                // Do we need to move the element?
                if (second.PreviousInVector == null || second.PreviousInVector.Index < index1)
                {
                    second.Index = index1;
                    return;
                }

                // Move the element back
                var element = second.PreviousInVector;
                Remove(second);
                while (element.PreviousInVector != null && element.PreviousInVector.Index > index1)
                {
                    element = element.PreviousInVector;
                }

                // We now have the element below the insertion point
                if (element.PreviousInVector == null)
                {
                    _firstInVector = second;
                }
                else
                {
                    element.PreviousInVector.NextInVector = second;
                }
                second.PreviousInVector  = element.PreviousInVector;
                element.PreviousInVector = second;
                second.NextInVector      = element;
                second.Index             = index1;
            }
            else if (second == null)
            {
                // Do we need to move the element?
                if (first.NextInVector == null || first.NextInVector.Index > index2)
                {
                    first.Index = index2;
                    return;
                }

                // Move element forward
                var element = first.NextInVector;
                Remove(first);
                while (element.NextInVector != null && element.NextInVector.Index < index2)
                {
                    element = element.NextInVector;
                }

                // We now have the first element above the insertion point
                if (element.NextInVector == null)
                {
                    _lastInVector = first;
                }
                else
                {
                    element.NextInVector.PreviousInVector = first;
                }
                first.NextInVector     = element.NextInVector;
                element.NextInVector   = first;
                first.PreviousInVector = element;
                first.Index            = index2;
            }
            else
            {
                // Are they adjacent or not?
                if (first.NextInVector == second)
                {
                    // Correct surrounding links
                    if (first.PreviousInVector == null)
                    {
                        _firstInVector = second;
                    }
                    else
                    {
                        first.PreviousInVector.NextInVector = second;
                    }
                    if (second.NextInVector == null)
                    {
                        _lastInVector = first;
                    }
                    else
                    {
                        second.NextInVector.PreviousInVector = first;
                    }

                    // Correct element links
                    first.NextInVector      = second.NextInVector;
                    second.PreviousInVector = first.PreviousInVector;
                    first.PreviousInVector  = second;
                    second.NextInVector     = first;
                    first.Index             = index2;
                    second.Index            = index1;
                }
                else
                {
                    // Swap surrounding links
                    if (first.PreviousInVector == null)
                    {
                        _firstInVector = second;
                    }
                    else
                    {
                        first.PreviousInVector.NextInVector = second;
                    }
                    first.NextInVector.PreviousInVector = second;
                    if (second.NextInVector == null)
                    {
                        _lastInVector = first;
                    }
                    else
                    {
                        second.NextInVector.PreviousInVector = first;
                    }
                    second.PreviousInVector.NextInVector = first;

                    // Swap element links
                    var element = first.PreviousInVector;
                    first.PreviousInVector  = second.PreviousInVector;
                    second.PreviousInVector = element;

                    element             = first.NextInVector;
                    first.NextInVector  = second.NextInVector;
                    second.NextInVector = element;

                    first.Index  = index2;
                    second.Index = index1;
                }
            }
        }