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); }
/// <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); }
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; }
internal static Expected <T> GetExpected <T>(this Singly <T> singly) => new Expected <T> { Count = singly.Count, Head = singly.Head, Tail = singly.Tail };
internal static void InternalValidation <T>(this Singly <T> list) { if (list.IsEmpty) { Throw.ArgumentNullException(nameof(list)); } }
public void IsPalindrome_ReturnsFalse_WhenListIsEmpty() { var singly = new Singly <string>(); var actual = singly.IsPalindrome(); Assert.False(actual); }
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); }
public void LoopStartNode_ReturnsNull_WhenListIsEmpty() { var singly = new Singly <int>(); var actualNode = singly.LoopStartNode(); Assert.Null(actualNode); }
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) };
public static SinglyNode <T> MiddleNode <T>(this Singly <T> list) { if (list.IsEmpty) { return(null); } return(list.InternalMiddleNode()); }
public void MiddleNode_ReturnsNull_WhenListIsEmpty() { var singly = new Singly <int>(); var actual = singly.MiddleNode(); Assert.Null(actual); Assert.True(singly.IsEmpty); }
public void LoopLength_ReturnsZero_WhenListIsEmpty() { var singly = new Singly <int>(); var actual = singly.LoopLength(); Assert.True(0 == actual); Assert.True(singly.IsEmpty); }
public void MergeSort_ReturnsNull_WhenBothListsAreEmpty() { var actualSinglyOne = new Singly <int>(); var actualSinglyTwo = new Singly <int>(); var actualSingly = actualSinglyOne.MergeSort(actualSinglyTwo); Assert.Null(actualSingly); }
public static void MergeSort(this Singly <int> unsortedList) { if (unsortedList.Count < 2) { return; } unsortedList.Head = unsortedList.Head.InternalMergeSort(); unsortedList.InternalSetupSinglyAfterMergeSort(); }
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); }
public static void SetupLoop <T>(this Singly <T> list, T item) { var node = list.GetNode(item); if (node == null) { return; } list.Tail.Next = node; }
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); }
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); }
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); }
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); }
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; }
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(); }
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); }
[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); }
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); }
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); } }
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); }
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); }
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; } }
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); }