// Finds the first node of the loop func FindCorruptNode(l ds.LinkedList) *ds.Node { head := l.Head() slowRunner := head fastRunner := head.Next() corruptNode := &ds.Node{} // Find the Collusion for { // There is no loop if slowRunner.Next() == nil || fastRunner.Next() == nil { return nil } // Move slow runner one point slowRunner = slowRunner.Next() // Move fast runner two points fastRunner = fastRunner.Next().Next() // Are they matched ? if slowRunner == fastRunner { fastRunner = fastRunner.Next() break } } // Find the collision point slowRunner = head for { if slowRunner == fastRunner { corruptNode = slowRunner break } // Move one point ahead for two of runners slowRunner = slowRunner.Next() fastRunner = fastRunner.Next() } return corruptNode }
func initializeLoopedList() []findCorruptNodeTestPair { l1 := ds.LinkedList{} l2 := ds.LinkedList{} node := &ds.Node{} // Create a looped linked list // 0->1->2->3->4->5->6->3->4->5->6->3->4->5->6... for i := 0; i < 6; i++ { n := ds.Node{} n.SetValue(i) l1.Add(&n) if i == 5 { temp := l1.Head().Next().Next().Next() node = temp l1.Add(temp) } } // Create a non-looped linked list for i := 0; i < 10; i++ { n := ds.Node{} n.SetValue(i) l2.Add(&n) } // we can expand test cases var loopTests = []findCorruptNodeTestPair{ {l1, node}, {l2, nil}, // no loop } return loopTests }
// Gives sliced linked list from kth element to last element. // Also it assumes that, we don't know size&last element of the linkedlist. func Slice(l datastructures.LinkedList, kth int) *datastructures.LinkedList { if kth <= 0 { return nil } current := l.Head() runner := current sliced_list := datastructures.LinkedList{} count := 0 for current != nil { runner = current if count == kth { sliced_list.SetHead(current) for runner != nil { runner = runner.Next() } break sliced_list.SetTail(current) } count++ current = current.Next() } if sliced_list.Head() != nil { return &sliced_list } else { return nil } }
func initializeReverseList() []sumLinkedListReverseTestPair { l1 := datastructures.LinkedList{} l2 := datastructures.LinkedList{} // l2 : 1->2->3 = 321 // l1 : 1->2->3->4 = 4321 // summed value = 4642 value := 4642 // Create l1 : 1->2->3->4 = 4321 for i := 1; i < 5; i++ { n := datastructures.Node{} n.SetValue(i) if i == 4 { l1.Add(&n) continue } l1.Add(&n) } // Create l2 : 1->2->3 = 321 for i := 1; i < 4; i++ { n := datastructures.Node{} n.SetValue(i) l2.Add(&n) } // we can expand test cases var reverseTests = []sumLinkedListReverseTestPair{ {l1, l2, value}, } return reverseTests }
func initializePalindromeTests() []palindromeTestPair { l1 := ds.LinkedList{} // palindrome l2 := ds.LinkedList{} // non-palindrome // create a palindrome list // move until half of the list to create a palindrome list for i := 0; i < 5; i++ { n := ds.Node{} n.SetValue(i) l1.Add(&n) } // move from half of the list to create a palindrome list for i := 5; i >= 0; i-- { n := ds.Node{} n.SetValue(i) l1.Add(&n) } // create a non-palindrome list for i := 0; i < 10; i++ { n := ds.Node{} n.SetValue(i) l2.Add(&n) } // we can expand test cases var palindromeTests = []palindromeTestPair{ {l1, true}, {l2, false}, } return palindromeTests }
// Removes duplicate nodes inside the given linkedlist func RemoveDuplicates(l *datastructures.LinkedList) { current := l.Head() for current != nil { runner := current for runner.Next() != nil { if runner.Next().GetValue() == current.GetValue() { runner.SetNext(runner.Next().Next()) } else { runner = runner.Next() } } current = current.Next() } }
// checks wheter given list is palindrome func IsPalindrome(l ds.LinkedList) bool { head := l.Head() // reverse given list reversed_list := reverseList(l) reversed_head := reversed_list.Head() // checks items until half of the list for i := 0; i < l.Len()/2; i++ { if head.GetValue() != reversed_head.GetValue() { return false } head = head.Next() reversed_head = reversed_head.Next() } return true }
// reverse given list func reverseList(l ds.LinkedList) ds.LinkedList { temp := l.Copy() reversed_list := ds.LinkedList{} head := temp.Head() current_node := head var prev_node *ds.Node for { if current_node != nil { next_node := current_node.Next() current_node.SetNext(prev_node) prev_node = current_node current_node = next_node } else { reversed_list.SetHead(prev_node) break } } return reversed_list }
func initializeForwardList() []sumLinkedListForwardTestPair { l1 := datastructures.LinkedList{} l2 := datastructures.LinkedList{} // l1 : 1->2->3->4 = 1234 // l2 : 1->2->3 = 123 // summed value = 1357 value := 1357 // Create l1 : 1->2->3->4 = 1234 for i := 1; i < 5; i++ { n := datastructures.Node{} n.SetValue(i) l1.Add(&n) } // Create l2 : 1->2->3 = 123 for i := 1; i < 4; i++ { n := datastructures.Node{} n.SetValue(i) l2.Add(&n) } // we can expand test cases var forwardTests = []sumLinkedListForwardTestPair{ {l1, l2, value}, } return forwardTests }
func TestDeleteNode(t *testing.T) { deleteNodeTests := initializeDeleteNode() for _, test := range deleteNodeTests { // save original list in a temporary list temp := datastructures.LinkedList{} for elem := range test.orig.GetElements() { n := datastructures.Node{} n.SetValue(elem) temp.Add(&n) } DeleteNode(&test.node) // item by item check through two lists for i := 0; i < test.orig.Len(); i++ { if test.orig.Find(i) != test.result.Find(i) { t.Error("For ", temp.GetElements(), "Expected", test.result.GetElements(), "got", test.orig.GetElements()) } } } }
// Sum up two linked list in reverse order // Input:(7-> 1 -> 6) + (5 -> 9 -> 2).Thatis,617 + 295. // Output: 2 -> 1 -> 9.That is, 912. // we assume that, result integer does not exceed integer size func SumLinkedListReverse(l1 ds.LinkedList, l2 ds.LinkedList) int { head1 := l1.Head() head2 := l2.Head() num1 := 0 num2 := 0 multiplier := 1 // convert l1 list to int for head1 != nil { num1 += multiplier * head1.GetValue() multiplier = multiplier * 10 head1 = head1.Next() } multiplier = 1 // convert l2 list to int for head2 != nil { num2 += multiplier * head2.GetValue() multiplier = multiplier * 10 head2 = head2.Next() } return num1 + num2 }
// Sum up two linked list in forward order // Input:(6 -> 1 -> 7) + (2 -> 9 -> 5).Thatis,617 + 295. // Output: 9 -> 1 -> 2.That is, 912. // we assume that, result integer does not exceed integer size func SumLinkedListForward(l1 ds.LinkedList, l2 ds.LinkedList) int { head1 := l1.Head() head2 := l2.Head() num1 := 0 num2 := 0 multiplier1 := exp(10, l1.Len()-1) multiplier2 := exp(10, l2.Len()-1) // convert l1 list to int for head1 != nil { num1 += multiplier1 * head1.GetValue() multiplier1 = multiplier1 / 10 head1 = head1.Next() } // convert l2 list to int for head2 != nil { num2 += multiplier2 * head2.GetValue() multiplier2 = multiplier2 / 10 head2 = head2.Next() } return num1 + num2 }
func initializeSlice() []sliceTestPair { orig := datastructures.LinkedList{} for i := 0; i < 10; i++ { n := &datastructures.Node{} n.SetValue(i) orig.Add(n) } target := datastructures.LinkedList{} for i := 3; i < 10; i++ { n := &datastructures.Node{} n.SetValue(i) target.Add(n) } var sliceTests = []sliceTestPair{ {orig, &target, 3}, {orig, nil, 30}, {orig, nil, -3}, } return sliceTests }
func initializePartitionList() []partitionListTestPair { orig := datastructures.LinkedList{} result := datastructures.LinkedList{} value := 4 for i := 0; i < 10; i++ { n := datastructures.Node{} n.SetValue(i) // Set before values if i < value { orig.Add(&n) // Set after values } else { result.Add(&n) } } // we can expand test cases var partitionListTests = []partitionListTestPair{ {orig, result, value}, } return partitionListTests }
func initializeDeleteNode() []deleteNodeTestPair { node := datastructures.Node{} orig := datastructures.LinkedList{} target := datastructures.LinkedList{} for i := 0; i < 10; i++ { n := datastructures.Node{} n.SetValue(i) orig.Add(&n) // will delete this node // so, don't add this node to result list if i == 4 { node = n } else { target.Add(&n) } } // we can expand test cases var deleteNodeTests = []deleteNodeTestPair{ {orig, target, node}, } return deleteNodeTests }
func TestRemoveDuplicates(t *testing.T) { l := datastructures.LinkedList{} for i := 0; i <= 10; i++ { n := &datastructures.Node{} n.SetValue(i % 3) l.Add(n) } RemoveDuplicates(&l) if l.Len() != 3 { t.Error("Wrong length, Len() must be", 3) } if l.Find(0) == nil || l.Find(1) == nil || l.Find(2) == nil { t.Error("Wrong deletion for one of the elements.") } }
// partition given list into two parts due to the given value // and then merge them together. func PartitionList(l datastructures.LinkedList, value int) datastructures.LinkedList { beforeValue := datastructures.LinkedList{} afterValue := datastructures.LinkedList{} head := l.Head() for head != nil { n := datastructures.Node{} n.SetValue(head.GetValue()) if head.GetValue() < value { beforeValue.Add(&n) } else { afterValue.Add(&n) } head = head.Next() } beforeValue.SetTail(afterValue.Head()) return beforeValue }