示例#1
0
        private static SinglyNode <T> InternalMiddleNode <T>(this Singly <T> list)
        {
            if (list.IsEmpty)
            {
                Throw.ArgumentNullException(nameof(list));
            }
            if (list.Head.Next == null || list.Head.Next.Next == null)
            {
                return(list.Head);
            }

            var hare     = list.Head;
            var tortoise = list.Head;

            while (hare.Next != null)
            {
                hare = hare.Next;
                if (hare.Next == null)
                {
                    break;
                }

                hare     = hare.Next;
                tortoise = tortoise.Next;
            }

            return(tortoise);
        }
示例#2
0
        /// <summary>
        /// Merges 2 sorted lists.
        /// NOTE: Both lists must be sorted in order for this method to work correctly.
        /// </summary>
        /// <param name="sortedList1">The sorted list one.</param>
        /// <param name="sortedList2">The sorted list two.s</param>
        /// <returns>A new list which is a combination of both the sorted lists.</returns>
        public static Singly <int> MergeSort(this Singly <int> sortedList1, Singly <int> sortedList2)
        {
            if (sortedList1.IsEmpty && sortedList2.IsEmpty)
            {
                return(null);
            }
            if (sortedList1.IsEmpty && !sortedList2.IsEmpty)
            {
                return(sortedList2);
            }
            if (!sortedList1.IsEmpty && sortedList2.IsEmpty)
            {
                return(sortedList1);
            }

            var singly = new Singly <int>
            {
                Count = sortedList1.Count + sortedList2.Count,
                Head  = InternalMerge(sortedList1.Head, sortedList2.Head)
            };

            if (sortedList1.Tail.Item > sortedList2.Tail.Item)
            {
                singly.Tail = sortedList1.Tail;
            }
            else
            {
                singly.Tail = sortedList2.Tail;
            }

            return(singly);
        }
示例#3
0
        public static void Reverse <T>(this Singly <T> list)
        {
            if (list.IsEmpty)
            {
                return;
            }
            if (list.Head.Next == null)
            {
                return;
            }

            SinglyNode <T> prev = null, current = list.Head, next = list.Head.Next;

            list.Tail = list.Head;
            while (next != null)
            {
                current.Next = prev;
                prev         = current;
                current      = next;
                next         = current.Next;
            }
            current.Next = prev;
            prev         = current;
            list.Head    = prev;
        }
示例#4
0
 internal static Expected <T> GetExpected <T>(this Singly <T> singly)
 => new Expected <T>
 {
     Count = singly.Count,
     Head  = singly.Head,
     Tail  = singly.Tail
 };
示例#5
0
 internal static void InternalValidation <T>(this Singly <T> list)
 {
     if (list.IsEmpty)
     {
         Throw.ArgumentNullException(nameof(list));
     }
 }
示例#6
0
        public void IsPalindrome_ReturnsFalse_WhenListIsEmpty()
        {
            var singly = new Singly <string>();

            var actual = singly.IsPalindrome();

            Assert.False(actual);
        }
示例#7
0
 private void AssertHeadTailReferencesAndCount <T>(
     Expected <T> expected
     , Singly <T> singly)
 {
     Assert.Equal(expected.Head, singly.Head);
     Assert.Equal(expected.Tail, singly.Tail);
     Assert.True(expected.Count == singly.Count);
 }
示例#8
0
        public void LoopStartNode_ReturnsNull_WhenListIsEmpty()
        {
            var singly = new Singly <int>();

            var actualNode = singly.LoopStartNode();

            Assert.Null(actualNode);
        }
示例#9
0
 internal static Expected <T> GetExpected <T>(this Singly <T> singly
                                              , T expectedHeadItem
                                              , T expectedTailItem)
 => new Expected <T>
 {
     Count = singly.Count,
     Head  = singly.GetNode(expectedHeadItem),
     Tail  = singly.GetNode(expectedTailItem)
 };
示例#10
0
        public static SinglyNode <T> MiddleNode <T>(this Singly <T> list)
        {
            if (list.IsEmpty)
            {
                return(null);
            }

            return(list.InternalMiddleNode());
        }
示例#11
0
        public void MiddleNode_ReturnsNull_WhenListIsEmpty()
        {
            var singly = new Singly <int>();

            var actual = singly.MiddleNode();

            Assert.Null(actual);
            Assert.True(singly.IsEmpty);
        }
示例#12
0
        public void LoopLength_ReturnsZero_WhenListIsEmpty()
        {
            var singly = new Singly <int>();

            var actual = singly.LoopLength();

            Assert.True(0 == actual);
            Assert.True(singly.IsEmpty);
        }
示例#13
0
        public void MergeSort_ReturnsNull_WhenBothListsAreEmpty()
        {
            var actualSinglyOne = new Singly <int>();
            var actualSinglyTwo = new Singly <int>();

            var actualSingly = actualSinglyOne.MergeSort(actualSinglyTwo);

            Assert.Null(actualSingly);
        }
示例#14
0
        public static void MergeSort(this Singly <int> unsortedList)
        {
            if (unsortedList.Count < 2)
            {
                return;
            }

            unsortedList.Head = unsortedList.Head.InternalMergeSort();
            unsortedList.InternalSetupSinglyAfterMergeSort();
        }
示例#15
0
        public void LoopLength_ReturnsZero_WhenLoopDoesNotExistsInTheList(
            string actualStr)
        {
            var singly = new Singly <int>(actualStr.ConvertToInts());

            var actualLoopLength = singly.LoopLength();

            Assert.True(0 == actualLoopLength);
            Assert.False(singly.IsEmpty);
        }
示例#16
0
        public static void SetupLoop <T>(this Singly <T> list, T item)
        {
            var node = list.GetNode(item);

            if (node == null)
            {
                return;
            }
            list.Tail.Next = node;
        }
示例#17
0
        public void LoopStartNode_ReturnsNull_WhenLoopDoesNotExists(
            string strList)
        {
            var singly   = new Singly <int>(strList.ConvertToInts());
            var expected = singly.GetExpected();

            var actualNode = singly.LoopStartNode();

            Assert.Null(actualNode);
            AssertHeadTailReferencesAndCount(expected, singly);
        }
示例#18
0
        public void IsPalindrome_ReturnsTrue_WhenListIsPalindrome(
            string strList)
        {
            var singly   = new Singly <int>(strList.ConvertToInts());
            var expected = singly.GetExpected();

            var actual = singly.IsPalindrome();

            Assert.True(actual);
            AssertHeadTailReferencesAndCount(expected, singly);
        }
示例#19
0
        public void MiddleNode_ReturnsTheMiddleNode_WhenListIsNotEmpty(
            string actualStr
            , int expectedItem)
        {
            var singly   = new Singly <int>(actualStr.ConvertToInts());
            var expected = singly.GetExpected();

            var actual = singly.MiddleNode();

            Assert.True(expectedItem == actual.Item);
            AssertHeadTailReferencesAndCount(expected, singly);
        }
示例#20
0
        public void LoopExists_ReturnsFalse_WhenLoopDoesNotExistsInTheList(
            string strList
            , int startOfLoop)
        {
            var singly = new Singly <int>(strList.ConvertToInts());

            singly.SetupLoop(startOfLoop);

            var actual = singly.LoopExists();

            Assert.False(actual);
        }
示例#21
0
        private static void InternalSetupSinglyAfterMergeSort(this Singly <int> list)
        {
            var current = list.Head;

            list.Count = 1;
            while (current.Next != null)
            {
                current = current.Next;
                ++list.Count;
            }
            list.Tail = current;
        }
示例#22
0
        public void MergeSort_SortsTheNodesInAscendingOrder_WhenListIsNotSorted(
            string actualStr
            , string expectedStr)
        {
            var actualSingly   = new Singly <int>(actualStr.ConvertToInts());
            var expectedSingly = new Singly <int>(expectedStr.ConvertToInts());

            actualSingly.MergeSort();

            AssertExpectedAndActualListContents(expectedSingly, actualSingly);
            expectedSingly.Clear();
            actualSingly.Clear();
        }
示例#23
0
        public static SinglyNode <T> NthNode <T>(this Singly <T> list, int nTh)
        {
            InternalValidationForListAndIndex(list, nTh);

            var current = list.Head;

            while (--nTh != 0)
            {
                current = current.Next;
            }

            return(current);
        }
示例#24
0
        [InlineData("2,3,9,7", "1,5,4", "1,2,3,5,4,9,7")]   // None is sorted.
        public void MergeSort_ReturnsNewUnsortedList_WhenBothListsAreNotSorted(
            string actualStr1
            , string actualStr2
            , string expectedStr)
        {
            var actualSinglyOne = new Singly <int>(actualStr1.ConvertToInts());
            var actualSinglyTwo = new Singly <int>(actualStr2.ConvertToInts());
            var expectedSingly  = new Singly <int>(expectedStr.ConvertToInts());

            var actualSingly = actualSinglyOne.MergeSort(actualSinglyTwo);

            AssertExpectedAndActualListContents(expectedSingly, actualSingly);
            ClearSingly(actualSingly, actualSinglyOne, actualSinglyTwo, expectedSingly);
        }
示例#25
0
        public void LoopLength_ReturnsLengthOfLoop_WhenLoopExistsInTheList(
            string strList
            , int startOfLoop
            , int expectedLoopLength)
        {
            var singly   = new Singly <int>(strList.ConvertToInts());
            var expected = singly.GetExpected();

            singly.SetupLoop(startOfLoop);

            var actualLoopLength = singly.LoopLength();

            Assert.True(expectedLoopLength == actualLoopLength);
            AssertHeadTailReferencesAndCount(expected, singly);
        }
示例#26
0
 private static void InternalValidationForListAndIndex <T>(Singly <T> list, int nTh)
 {
     if (list == null)
     {
         Throw.ArgumentNullException(nameof(list));
     }
     if (nTh < 1)
     {
         Throw.ArgumentOutOfRangeException(nameof(nTh), Message.OnSinglyLinkedList.NthMustBePositiveNonZero);
     }
     if (nTh > list.Count)
     {
         Throw.ArgumentOutOfRangeException(nameof(nTh), Message.OnSinglyLinkedList.NthCannotBeGreaterThanListCount);
     }
 }
示例#27
0
        public static bool IsPalindrome <T>(this Singly <T> list)
        {
            if (list.IsEmpty)
            {
                return(false);
            }

            var comparer = EqualityComparer <T> .Default;

            if (!comparer.Equals(list.Head.Item, list.Tail.Item))
            {
                return(false);
            }
            if (list.Count == 1)
            {
                return(true);
            }
            if (list.Count == 2 || list.Count == 3)
            {
                return(comparer.Equals(list.Head.Item, list.Tail.Item));
            }

            // First get the middle node of the list and then add all the item of the second half of the list to stack.
            var middle          = list.InternalMiddleNode();
            var secondHalfStart = (list.Count & 1) == 1 ? middle.Next : middle;
            var items           = new DsGeneric.Stack <T>();

            while (secondHalfStart != null)
            {
                items.Push(secondHalfStart.Item);
                secondHalfStart = secondHalfStart.Next;
            }

            // Compare first half of the list with stack elements by poping them.
            var current = list.Head;

            while (current != middle)
            {
                if (!comparer.Equals(current.Item, items.Pop()))
                {
                    return(false);
                }
                current = current.Next;
            }
            items.Clear();

            return(true);
        }
示例#28
0
        public void LoopStartNode_ReturnsStartNodeOfLoop_WhenLoopExists(
            string strList
            , int startOfLoop)
        {
            var singly       = new Singly <int>(strList.ConvertToInts());
            var expected     = singly.GetExpected();
            var expectedNode = singly.GetNode(startOfLoop);

            singly.SetupLoop(startOfLoop);

            var actualNode = singly.LoopStartNode();

            Assert.Equal(expectedNode, actualNode);
            Assert.True(expectedNode.Item == actualNode.Item);
            AssertHeadTailReferencesAndCount(expected, singly);
        }
示例#29
0
        private void AssertExpectedAndActualListContents <T>(
            Singly <T> expected
            , Singly <T> actual)
        {
            Assert.True(expected.Count == actual.Count);

            var comparer        = EqualityComparer <T> .Default;
            var expectedCurrent = expected.Head;
            var actualCurrent   = actual.Head;

            while (expectedCurrent != null && actualCurrent != null)
            {
                Assert.True(comparer.Equals(expectedCurrent.Item, actualCurrent.Item));
                expectedCurrent = expectedCurrent.Next;
                actualCurrent   = actualCurrent.Next;
            }
        }
示例#30
0
        public static SinglyNode <T> LoopStartNode <T>(this Singly <T> list)
        {
            var meetingNode = list.InternalHareTortoiseMeetNode();

            if (meetingNode == null)
            {
                return(null);
            }

            var current = list.Head;

            meetingNode = meetingNode.Next;
            while (current != meetingNode)
            {
                current     = current.Next;
                meetingNode = meetingNode.Next;
            }

            return(current);
        }