//Return the index of the last occurrence of the given item. Starting from the index start. O(n)
        public int LastIndexOf(Object item, int start, int count)
        {
            if (start < 0 || start >= _size)
            {
                throw new ArgumentOutOfRangeException("start", "The start index is out of range");
            }
            if (count < 0 || count > _size - start)
            {
                throw new ArgumentOutOfRangeException("count", " The count is out of range");
            }

            SinglyLinkedNode curr = GetNodeAt(start);

            int res = -1;

            for (int i = 0; i < count; i++)
            {
                if (curr.Item.Equals(item))
                {
                    res = i;
                }
                curr = curr.Next;
            }

            if (res == -1)
            {
                return(res);
            }
            return(res + start);
        }
        //Return the index of the first occurrence of the given item beginning the search at index start, searching through a length of count. O(n)
        public int IndexOf(Object item, int start, int count)
        {
            if (start < 0 || start >= _size)
            {
                throw new ArgumentOutOfRangeException("start", "The start index is out of range");
            }
            if (count < 0 || start > _size - count)
            {
                throw new ArgumentOutOfRangeException("count", "The count is out of range");
            }

            SinglyLinkedNode curr = GetNodeAt(start);

            int res = start;

            while (res < count + start)
            {
                if (curr.Item.Equals(item))
                {
                    return(res);
                }
                curr = curr.Next;
                res++;
            }
            return(-1);
        }
        //Remove the items trough the specified range. O(n)
        public void RemoveSection(int start, int count)
        {
            if (start < 0 || start >= _size)
            {
                throw new ArgumentOutOfRangeException("start", "The start index is out of range");
            }
            if (count < 0 || count > _size - start)
            {
                throw new ArgumentOutOfRangeException("count", "The count is out of range");
            }

            if (start == 0 && count == _size)
            {
                _head = null;
                _size = 0;
                return;
            }

            if (start == 0)   //Base case remove from front
            {
                SinglyLinkedNode newHead = GetNodeAt(count);
                _head = newHead;
            }
            else
            {
                SinglyLinkedNode prev = GetNodeAt(start - 1);
                SinglyLinkedNode next = GetNodeAtFrom(start + count, prev, start - 1);
                prev.Next = next;
            }
            _size -= count;
        }
Пример #4
0
    /// <summary>
    /// Removes the element at the specified index of the <see cref="SinglyLinkedList&lt;T&gt;"/>.
    /// </summary>
    /// <param name="index">The zero-based index of the element to remove.</param>
    /// <exception cref="System.ArgumentOutOfRangeException">Thrown when
    /// <paramref name="index"/> is less than zero or <paramref name="index"/> is
    /// greater than or equal to <see cref="SinglyLinkedList&lt;T&gt;"/>.Count.</exception>
    public void RemoveAt(int index)
    {
        if (index < 0 || index >= this.size)
        {
            throw new ArgumentOutOfRangeException(
                      "index",
                      "Index was out of range. Must be non-negative and less than the size of the collection.");
        }

        if (index == 0)
        {
            this.RemoveBeginning();
            return;
        }

        // find the item at the specified index
        int currentIndex = 0;
        SinglyLinkedNode <T> currentNode = this.firstNode;

        while (currentIndex < index - 1)
        {
            currentNode = currentNode.NextNode;
            currentIndex++;
        }

        this.RemoveAfter(currentNode);
    }
        public void Sample()
        {
            IStack <SinglyLinkedNode <String> > stack = new LinkedStack <String>();

            Int32 cycleNumber = 10;
            Int32 popNumber   = cycleNumber / 2;
            SinglyLinkedNode <String> tmpSequentialNode = null;

            for (Int32 i = 0; i < cycleNumber; i++)
            {
                stack.Push(new SinglyLinkedNode <String>()
                {
                    Data = i.ToString()
                });
                if (i >= popNumber)
                {
                    stack.Pop();
                }
                else
                {
                    tmpSequentialNode = stack.Get();
                    Console.WriteLine($"SinglyLinkedNode data is 【{tmpSequentialNode.Data}】");
                }
            }

            Console.WriteLine($"【{MethodBase.GetCurrentMethod().DeclaringType.FullName}】 end.");
        }
Пример #6
0
        //Remove the item from the set if it is present. O(n)
        public void Remove(Object item)
        {
            SinglyLinkedNode curr = _head;

            if (curr.Item.Equals(item))
            {
                _head = _head.Next;
                _size--;
                return;
            }
            SinglyLinkedNode prev = curr;

            curr = curr.Next;
            while (curr != null)
            {
                if (curr.Item.Equals(item))
                {
                    prev.Next = curr.Next;
                    _size--;
                    break;
                }
                prev = curr;
                curr = curr.Next;
            }
        }
Пример #7
0
    /// <summary>
    /// Inserts an element into the <see cref="SinglyLinkedList&lt;T&gt;"/> at the specified index.
    /// </summary>
    /// <param name="index">The zero-based index at which item should be inserted.</param>
    /// <param name="item">The object to insert. The value can be null for reference types.</param>
    /// <exception cref="System.ArgumentOutOfRangeException">Thrown when
    /// <paramref name="index"/> is less than zero or <paramref name="index"/> is
    /// greater than or equal to <see cref="SinglyLinkedList&lt;T&gt;"/>.Count.</exception>
    public void Insert(int index, T item)
    {
        if (index < 0 || index > this.size)
        {
            throw new ArgumentOutOfRangeException(
                      "index",
                      "Index was out of range. Must be non-negative and less than or equal to the size of the collection.");
        }

        SinglyLinkedNode <T> newNode = new SinglyLinkedNode <T>(item);

        if (index == 0)
        {
            this.InsertBeginning(newNode);
            return;
        }

        // find the item at the specified index
        int currentIndex = 0;
        SinglyLinkedNode <T> currentNode = this.firstNode;

        while (currentIndex < index - 1)
        {
            currentNode = currentNode.NextNode;
            currentIndex++;
        }

        this.InsertAfter(currentNode, newNode);
    }
Пример #8
0
 //get next item in a LIFO manner
 public T Pop()
 {
     //empty list condition
     if (this.Head == null && this.Tail == null)
     {
         throw new InvalidOperationException(); //if we have an empty list then throw an invalid operation exception
     }
     //single item in list condition
     else if (this.Head == this.Tail)
     {
         SinglyLinkedNode <T> nxt = this.Head; //make a reference to the top value of the stack
         this.Head = this.Tail = null;         //because we only have 1 value in the list, both head and tail will reset to null
         this._Count--;
         return(nxt.Data);                     //return the value in nxt
     }
     //otherwise fetch to head
     else
     {
         SinglyLinkedNode <T> nxt = this.Head; //make reference of the top value
         this.Head = this.Head.Next;           //move head to the next value
         nxt.Next  = null;                     //because nxt is a reference to the old head, we can set the next value to null will cause the garbage collector to pick it up
         this._Count--;
         return(nxt.Data);                     //return the value
     }
 }
Пример #9
0
 /// <summary>Attempts to remove an item from the start of the queue.</summary>
 /// <param name="item">The item dequeued if successful.</param>
 /// <returns>True if the operation succeeds, false if the queue was empty.</returns>
 public bool TryDequeue(out T item)
 {
     for (;;)
     {
         SinglyLinkedNode <T> curHead     = _head;
         SinglyLinkedNode <T> curTail     = _tail;
         SinglyLinkedNode <T> curHeadNext = curHead.Next;
         if (curHead == curTail)
         {
             if (curHeadNext == null)
             {
                 item = default(T);
                 return(false);
             }
             else
             {
                 Interlocked.CompareExchange(ref _tail, curHeadNext, curTail);   // assist obstructing thread
             }
         }
         if (Interlocked.CompareExchange(ref _head, curHeadNext, curHead) == curHead)
         {
             item = curHeadNext.Item;
             return(true);
         }
     }
 }
        public SinglyLinkedNode <T> RemoveDuplicates <T>(SinglyLinkedNode <T> headOfList)
        {
            if (headOfList == null)
            {
                throw new ArgumentNullException(nameof(headOfList));
            }

            var dict = new Dictionary <T, int>();

            var prev    = headOfList;
            var current = headOfList.Next;

            dict.Add(prev.Data, 1);
            while (current != null)
            {
                if (dict.ContainsKey(current.Data))
                {
                    prev.Next = current.Next; //removing node
                }
                else
                {
                    dict.Add(current.Data, 1);
                    prev = current;
                }
                current = current.Next;
            }
            return(headOfList);
        }
        public SinglyLinkedListImplementation <T> Merge <T>(SinglyLinkedNode <T> headOfFirstList, SinglyLinkedNode <T> headOfSecondList)
            where T : IComparable <T>
        {
            var resultList = new SinglyLinkedListImplementation <T>();

            var firstPointer  = headOfFirstList;
            var secondPointer = headOfSecondList;

            while (firstPointer != null && secondPointer != null)
            {
                if (firstPointer.Data.CompareTo(secondPointer.Data) < 0)
                {
                    resultList.AddAtEnd(firstPointer.Data);
                    firstPointer = firstPointer.Next;
                }
                else
                {
                    resultList.AddAtEnd(secondPointer.Data);
                    secondPointer = secondPointer.Next;
                }
            }

            while (firstPointer != null)
            {
                resultList.AddAtEnd(firstPointer.Data);
                firstPointer = firstPointer.Next;
            }

            while (secondPointer != null)
            {
                resultList.AddAtEnd(secondPointer.Data);
                secondPointer = secondPointer.Next;
            }
            return(resultList);
        }
Пример #12
0
 /// <summary>Pushes a collection of items to the top of the stack as a single atomic operation.</summary>
 /// <param name="collection">The items to push onto the stack.</param>
 /// <exception cref="ArgumentNullException">The collection was null.</exception>
 public void PushRange(IEnumerable <T> collection)
 {
     Validation.NullCheck(collection, "collection");
     using (IEnumerator <T> en = collection.GetEnumerator())
     {
         if (!en.MoveNext())
         {
             return;
         }
         var start = new SinglyLinkedNode <T>(en.Current);
         var end   = start;
         while (en.MoveNext())
         {
             var newNode = new SinglyLinkedNode <T>(en.Current);
             end.Next = newNode;
             end      = newNode;
         }
         var next = end.Next = _head.Next;
         for (;;)
         {
             SinglyLinkedNode <T> oldNext = Interlocked.CompareExchange(ref _head.Next, start, next);
             if (oldNext == next)
             {
                 return;
             }
             next = end.Next = oldNext;
         }
     }
 }
Пример #13
0
        public void ShouldReturn5thElementFromTheEndOfList()
        {
            var cut = new FindNodeFromEndOfLinkedList <int>();

            SinglyLinkedNode <int> n = new SinglyLinkedNode <int>(1)
            {
                Next = new SinglyLinkedNode <int>(2)
                {
                    Next = new SinglyLinkedNode <int>(8)
                    {
                        Next = new SinglyLinkedNode <int>(3)
                        {
                            Next = new SinglyLinkedNode <int>(7)
                            {
                                Next = new SinglyLinkedNode <int>(0)
                                {
                                    Next = new SinglyLinkedNode <int>(4)
                                }
                            }
                        }
                    }
                }
            };

            Assert.AreEqual(8, cut.Find(n, 5));
        }
Пример #14
0
        //get next item in a FIFO
        public T Dequeue()
        {
            //empty list condition
            if (this.Head == null && this.Tail == null)
            {
                throw new InvalidOperationException(); //if we have an empty list then throw an invalid operation exception
            }
            //single item in list condition
            else if (this.Head == this.Tail)
            {
                SinglyLinkedNode <T> nxt = this.Tail; //since we only have one value, we could reference either head or tail, to be consistent we will use tail
                this.Head = this.Tail = null;         //because we only have 1 value in the list, both head and tail will reset to null
                this._Count--;
                return(nxt.Data);                     //return the value in nxt
            }
            //otherwise fetch to tail
            else
            {
                SinglyLinkedNode <T> nxt = this.Tail; //make reference of the top value
                SinglyLinkedNode <T> ptr = this.Head; //we need a pointer because we need to get to the value 1 before the tail

                //because we use a singly linked list, we need to iterate from the top to get the value one before the tail, this is a performance issue we could
                //rectify by using a doubly linked list, then we could say this.Tail.Prev and make this an O(1) operation instead of O(n)
                while (ptr.Next != this.Tail)
                {
                    ptr = ptr.Next;
                }

                ptr.Next  = null; //unhook our pointer from the tail
                this.Tail = ptr;  //make tail point to the ptr
                this._Count--;
                return(nxt.Data); //return our value
            }
        }
Пример #15
0
        //Push a new item on top of the stack. O(1)
        public void Push(Object item)
        {
            SinglyLinkedNode newHead = new SinglyLinkedNode(item);

            newHead.Next = _head;
            _head        = newHead;
            _size++;
        }
Пример #16
0
        public T Pop()
        {
            var item = _first.Item;

            _first = _first.Next;
            Count--;
            return(item);
        }
Пример #17
0
        public T Dequeue()
        {
            var item = _first.Item;

            _first = _first.Next;
            Count--;
            return(item);
        }
Пример #18
0
 /// <summary>Moves to the next item.</summary>
 /// <returns>True if an item is found, false if it reaches the end of the queue.</returns>
 public bool MoveNext()
 {
     if (_node == _tail)
     {
         return(false);
     }
     _node = _node.Next;
     return(true);
 }
Пример #19
0
        /// <summary>Clears the queue as a single atomic operation.</summary>
        public void Clear()
        {
            SinglyLinkedNode <T> head = _head;
            SinglyLinkedNode <T> oldHead;

            while ((oldHead = Interlocked.CompareExchange(ref _head, _tail, head)) != head)
            {
                head = oldHead;
            }
        }
        public T Pop()
        {
            T ret = _head.Pop();

            if (_head.IsEmpty && _head.Next != null)
            {
                _head = _head.Next;
            }
            return(ret);
        }
Пример #21
0
            public static void PrintList(SinglyLinkedNode head)
            {
                var curNode = head;

                while (curNode != null)
                {
                    Console.Write($"{(curNode == head ? "" : "->")}{curNode.Data}");
                    curNode = curNode.Next;
                }
            }
Пример #22
0
        public void CopyTo(T[] array, int arrayIndex)
        {
            SinglyLinkedNode <T> ptr = this.Head;

            for (int i = arrayIndex; i < this._Count; i++)
            {
                array[i] = ptr.Data;
                ptr      = ptr.Next;
            }
        }
        //Reverse the items of the list trough the given range. O(n)
        public void ReverseSection(int start, int count)
        {
            if (start < 0 || start >= _size)
            {
                throw new ArgumentOutOfRangeException("start", "The start index is out of range");
            }
            if (count < 0 || count > _size + start)
            {
                throw new ArgumentOutOfRangeException("count", "The count is out of range");
            }

            SinglyLinkedNode begSegEnd = null;

            if (start != 0)
            {
                begSegEnd = GetNodeAt(start - 1);
            }


            SinglyLinkedNode endSegBeg;

            if (begSegEnd == null)
            {
                endSegBeg = GetNodeAt(count);
            }
            else
            {
                endSegBeg = GetNodeAtFrom(start + count, begSegEnd, start - 1);
            }


            SinglyLinkedNode curr = _head;

            if (begSegEnd != null)
            {
                curr = begSegEnd.Next;
            }

            for (int i = 0; i < count; i++)
            {
                SinglyLinkedNode nextCurr = curr.Next;
                curr.Next = endSegBeg;
                endSegBeg = curr;
                curr      = nextCurr;
            }

            if (begSegEnd == null)
            {
                _head = endSegBeg;
                return;
            }

            begSegEnd.Next = endSegBeg;
        }
Пример #24
0
            internal AtDequeuEnumerable(SlimConcurrentQueue <T> queue)
            {
                SinglyLinkedNode <T> head;
                SinglyLinkedNode <T> tail;

                while (Interlocked.CompareExchange(ref queue._head, tail = queue._tail, head = queue._head) != head)
                {
                }
                _start = head;
                _end   = tail;
            }
Пример #25
0
            /// <summary>Moves to the next item.</summary>
            /// <returns>True if an item is found, false if it reaches the end of the stack.</returns>
            public bool MoveNext()
            {
                SinglyLinkedNode <T> next = _node.Next;

                if (next == null)
                {
                    return(false);
                }
                _node = next;
                return(true);
            }
    public IEnumerator <SinglyLinkedNode <T> > GetEnumerator()
    {
        SinglyLinkedNode <T> currentNode = this;

        do
        {
            SinglyLinkedNode <T> returnNode = currentNode;
            currentNode = currentNode.NextNode;
            yield return(returnNode);
        }while (currentNode != null);
    }
Пример #27
0
        public void Push(T item)
        {
            var currentFirst = _first;

            _first = new SinglyLinkedNode <T>
            {
                Next = currentFirst,
                Item = item
            };
            Count++;
        }
Пример #28
0
        /// <summary>Attempts to obtain a the item at the start of the queue without removing it.</summary>
        /// <param name="item">The item found.</param>
        /// <returns>True if the method succeeds, false if the queue was empty.</returns>
        public bool TryPeek(out T item)
        {
            SinglyLinkedNode <T> node = _head.Next;

            if (node == null)
            {
                item = default(T);
                return(false);
            }
            item = node.Item;
            return(true);
        }
 public SinglyLinkedNode Push(T item)
 {
     if (_size == ArraySize - 1)
     {
         SinglyLinkedNode n = new SinglyLinkedNode();
         n.Next = this;
         n.Push(item);
         return(n);
     }
     _array[_size++] = item;
     return(this);
 }
        public void Delete()
        {
            var list = new SinglyLinkedList <int>();

            Assert.AreEqual(0, list.Count());

            /* Deleting an item from an empty list. */
            Assert.IsFalse(list.Delete(10));

            /* Deleting a non-existing item from a list with one element. */
            list.Insert(5);
            Assert.AreEqual(1, list.Count());
            Assert.IsFalse(list.Delete(10));
            Assert.AreEqual(1, list.Count());
            Assert.AreEqual(5, list.Head().Value);

            /* Deleting the only node from the list (aka. Head).*/
            Assert.AreEqual(1, list.Count());
            Assert.IsTrue(list.Delete(5));
            Assert.AreEqual(0, list.Count());
            Assert.IsNull(list.Head());

            /*Deleting a non-existing item from a list with 2 items. */
            var head = new SinglyLinkedNode <int>(5)
            {
                Next = new SinglyLinkedNode <int>(10)
            };

            list = new SinglyLinkedList <int>(head);

            Assert.AreEqual(2, list.Count());
            Assert.IsFalse(list.Delete(16));
            Assert.AreEqual(2, list.Count());

            /*Deleting an existing item from a list with 2 items*/
            Assert.AreEqual(2, list.Count());
            Assert.IsTrue(list.Delete(5));
            Assert.AreEqual(1, list.Count());
            Assert.AreEqual(10, list.Head().Value);
            Assert.IsNull(list.Head().Next);

            /* Deleting head from a list with 3 nodes.*/
            head = new SinglyLinkedNode <int>(10)
            {
                Next = new SinglyLinkedNode <int>(3)
            };
            head.Next.Next = new SinglyLinkedNode <int>(1);
            list           = new SinglyLinkedList <int>(head);
            Assert.AreEqual(3, list.Count());
            Assert.IsTrue(list.Delete(10));
            Assert.AreEqual(2, list.Count());
            Assert.AreEqual(3, list.Head().Value);
        }