From d36bf5d6ae53d2cdb3f32ee4d82767ee8bd52ede Mon Sep 17 00:00:00 2001 From: kavithajm <91771245+kavithajm@users.noreply.github.com> Date: Thu, 21 Oct 2021 11:41:16 +0530 Subject: [PATCH 1/4] Adding comb sort --- sort/combSort.go | 30 +++++++++++ sort/countingsort.go | 25 +++++++++ sort/sorts_test.go | 123 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 167 insertions(+), 11 deletions(-) create mode 100644 sort/combSort.go create mode 100644 sort/countingsort.go diff --git a/sort/combSort.go b/sort/combSort.go new file mode 100644 index 000000000..88b560052 --- /dev/null +++ b/sort/combSort.go @@ -0,0 +1,30 @@ +// Implementation of comb sort algorithm, an improvement of bubble sort +// Reference: https://www.geeksforgeeks.org/comb-sort/ + +package sort + +func getNextGap(gap int) int { + gap = (gap * 10) / 13 + if gap < 1 { + return 1 + } + return gap +} + +func combSort(data []int) []int { + n := len(data) + gap := n + swapped := true + + for gap != 1 || swapped { + gap = getNextGap(gap) + swapped = false + for i := 0; i < n-gap; i++ { + if data[i] > data[i+gap] { + data[i], data[i+gap] = data[i+gap], data[i] + swapped = true + } + } + } + return data +} diff --git a/sort/countingsort.go b/sort/countingsort.go new file mode 100644 index 000000000..9ac7fbdfc --- /dev/null +++ b/sort/countingsort.go @@ -0,0 +1,25 @@ +// countingsort.go +// description: Implementation of counting sort algorithm +// details: A simple counting sort algorithm implementation +// author [Phil](https://github.com/pschik) +// see sort_test.go for a test implementation, test function TestQuickSort + +// package sort provides primitives for sorting slices and user-defined collections +package sort + +func Count(data []int) []int { + var aMin, aMax = -1000, 1000 + count := make([]int, aMax-aMin+1) + for _, x := range data { + count[x-aMin]++ + } + z := 0 + for i, c := range count { + for c > 0 { + data[z] = i + aMin + z++ + c-- + } + } + return data +} diff --git a/sort/sorts_test.go b/sort/sorts_test.go index 3a015e687..4fde59f30 100644 --- a/sort/sorts_test.go +++ b/sort/sorts_test.go @@ -23,28 +23,24 @@ func testFramework(t *testing.T, sortingFunction func([]int) []int) { expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, name: "Reversed Unsigned", }, - //Sorted slice { input: []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, expected: []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, name: "Sorted Signed", }, - //Reversed slice { input: []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10}, expected: []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, name: "Reversed Signed", }, - //Reversed slice, even length { input: []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10}, expected: []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, name: "Reversed Signed #2", }, - //Random order with repetitions { input: []int{-5, 7, 4, -2, 6, 5, 8, 3, 2, -7, -1, 0, -3, 9, -6, -4, 10, 9, 1, -8, -9, -10}, @@ -98,8 +94,73 @@ func TestHeap(t *testing.T) { testFramework(t, HeapSort) } +func TestCount(t *testing.T) { + testFramework(t, Count) +} + func TestQuick(t *testing.T) { - testFramework(t, QuickSort) + testCases := []struct { + input []int + expected []int + name string + }{ + //Sorted slice + { + input: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + name: "Sorted Unsigned", + }, + //Reversed slice + { + input: []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, + expected: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + name: "Reversed Unsigned", + }, + //Sorted slice + { + input: []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + expected: []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + name: "Sorted Signed", + }, + //Reversed slice + { + input: []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10}, + expected: []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + name: "Reversed Signed", + }, + //Reversed slice, even length + { + input: []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10}, + expected: []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + name: "Reversed Signed #2", + }, + //Random order with repetitions + { + input: []int{-5, 7, 4, -2, 6, 5, 8, 3, 2, -7, -1, 0, -3, 9, -6, -4, 10, 9, 1, -8, -9, -10}, + expected: []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10}, + name: "Random order Signed", + }, + //Single-entry slice + { + input: []int{1}, + expected: []int{1}, + name: "Singleton", + }, + { + input: []int{}, + expected: []int{}, + name: "Empty Slice", + }, + } + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + QuickSort(test.input) + if !reflect.DeepEqual(test.input, test.expected) { + t.Errorf("test %s failed", test.name) + t.Errorf("actual %v expected %v", test.input, test.expected) + } + }) + } } func TestShell(t *testing.T) { @@ -122,6 +183,10 @@ func TestSelection(t *testing.T) { testFramework(t, SelectionSort) } +func TestComb(t *testing.T) { + testFramework(t, combSort) +} + //END TESTS func benchmarkFramework(b *testing.B, f func(arr []int) []int) { @@ -136,23 +201,18 @@ func benchmarkFramework(b *testing.B, f func(arr []int) []int) { //Reversed slice {[]int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "Reversed Unsigned"}, - //Sorted slice {[]int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "Sorted Signed"}, - //Reversed slice {[]int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10}, []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "Reversed Signed"}, - //Reversed slice, even length {[]int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10}, []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "Reversed Signed #2"}, - //Random order with repetitions {[]int{-5, 7, 4, -2, 6, 5, 8, 3, 2, -7, -1, 0, -3, 9, -6, -4, 10, 9, 1, -8, -9, -10}, []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10}, "Random order Signed"}, - //Empty slice {[]int{}, []int{}, "Empty"}, //Single-entry slice @@ -188,8 +248,45 @@ func BenchmarkHeap(b *testing.B) { benchmarkFramework(b, HeapSort) } +func BenchmarkCount(b *testing.B) { + benchmarkFramework(b, Count) +} + func BenchmarkQuick(b *testing.B) { - benchmarkFramework(b, QuickSort) + var sortTests = []struct { + input []int + expected []int + name string + }{ + //Sorted slice + {[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "Sorted Unsigned"}, + //Reversed slice + {[]int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, + []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "Reversed Unsigned"}, + //Sorted slice + {[]int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "Sorted Signed"}, + //Reversed slice + {[]int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10}, + []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "Reversed Signed"}, + //Reversed slice, even length + {[]int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10}, + []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "Reversed Signed #2"}, + //Random order with repetitions + {[]int{-5, 7, 4, -2, 6, 5, 8, 3, 2, -7, -1, 0, -3, 9, -6, -4, 10, 9, 1, -8, -9, -10}, + []int{-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10}, "Random order Signed"}, + //Empty slice + {[]int{}, []int{}, "Empty"}, + //Single-entry slice + {[]int{1}, []int{1}, "Singleton"}, + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + for _, test := range sortTests { + QuickSort(test.input) + } + } } func BenchmarkShell(b *testing.B) { @@ -213,4 +310,8 @@ func BenchmarkSelection(b *testing.B) { benchmarkFramework(b, SelectionSort) } +func BenchmarkComb(b *testing.B) { + benchmarkFramework(b, combSort) +} + //END BENCHMARKS From 68c83eb6b774750088fc07cf5cdea0758f6a5d9d Mon Sep 17 00:00:00 2001 From: kavithajm <91771245+kavithajm@users.noreply.github.com> Date: Fri, 5 Nov 2021 16:06:08 +0530 Subject: [PATCH 2/4] Update sort/combSort.go Co-authored-by: Taj --- sort/combSort.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sort/combSort.go b/sort/combSort.go index 88b560052..fa7b173d9 100644 --- a/sort/combSort.go +++ b/sort/combSort.go @@ -11,7 +11,7 @@ func getNextGap(gap int) int { return gap } -func combSort(data []int) []int { +func Comb(data []int) []int { n := len(data) gap := n swapped := true From 86762f70193e251755e86aab780afdf11159d760 Mon Sep 17 00:00:00 2001 From: kavithajm <91771245+kavithajm@users.noreply.github.com> Date: Tue, 9 Nov 2021 12:32:58 +0530 Subject: [PATCH 3/4] Updating test for comb sort --- sort/sorts_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sort/sorts_test.go b/sort/sorts_test.go index 483b2b7d0..be239205e 100644 --- a/sort/sorts_test.go +++ b/sort/sorts_test.go @@ -123,7 +123,7 @@ func TestSelection(t *testing.T) { } func TestComb(t *testing.T) { - testFramework(t, combSort) + testFramework(t, Comb) } func TestPigeonhole(t *testing.T) { @@ -221,7 +221,7 @@ func BenchmarkSelection(b *testing.B) { } func BenchmarkComb(b *testing.B) { - benchmarkFramework(b, combSort) + benchmarkFramework(b, Comb) } func BenchmarkPigeonhole(b *testing.B) { From 68b2cf9190236abd3182d18aeb8066abff644f21 Mon Sep 17 00:00:00 2001 From: github-action <${GITHUB_ACTOR}@users.noreply.github.com> Date: Wed, 10 Nov 2021 13:15:15 +0000 Subject: [PATCH 4/4] Updated Documentation in README.md --- README.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index a6d6afd99..a5c904b18 100644 --- a/README.md +++ b/README.md @@ -758,19 +758,20 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute. --- ##### Functions: -1. [`Count`](./sort/countingsort.go#L9): No description provided. -2. [`Exchange`](./sort/exchangesort.go#L6): No description provided. -3. [`HeapSort`](./sort/heapsort.go#L121): No description provided. -4. [`ImprovedSimpleSort`](./sort/simplesort.go#L25): ImprovedSimpleSort is a improve SimpleSort by skipping an unnecessary comparison of the first and last. This improved version is more similar to implementation of insertion sort -5. [`InsertionSort`](./sort/insertionsort.go#L3): No description provided. -6. [`Mergesort`](./sort/mergesort.go#L35): Mergesort Perform mergesort on a slice of ints -7. [`Pigeonhole`](./sort/pigeonholesort.go#L12): Pigeonhole sorts a slice using pigeonhole sorting algorithm. -8. [`QuickSort`](./sort/quicksort.go#L37): QuickSort Sorts the entire array -9. [`QuickSortRange`](./sort/quicksort.go#L24): QuickSortRange Sorts the specified range within the array -10. [`RadixSort`](./sort/radixsort.go#L35): No description provided. -11. [`SelectionSort`](./sort/selectionsort.go#L3): No description provided. -12. [`ShellSort`](./sort/shellsort.go#L3): No description provided. -13. [`SimpleSort`](./sort/simplesort.go#L11): No description provided. +1. [`Comb`](./sort/combSort.go#L14): No description provided. +2. [`Count`](./sort/countingsort.go#L9): No description provided. +3. [`Exchange`](./sort/exchangesort.go#L6): No description provided. +4. [`HeapSort`](./sort/heapsort.go#L121): No description provided. +5. [`ImprovedSimpleSort`](./sort/simplesort.go#L25): ImprovedSimpleSort is a improve SimpleSort by skipping an unnecessary comparison of the first and last. This improved version is more similar to implementation of insertion sort +6. [`InsertionSort`](./sort/insertionsort.go#L3): No description provided. +7. [`Mergesort`](./sort/mergesort.go#L35): Mergesort Perform mergesort on a slice of ints +8. [`Pigeonhole`](./sort/pigeonholesort.go#L12): Pigeonhole sorts a slice using pigeonhole sorting algorithm. +9. [`QuickSort`](./sort/quicksort.go#L37): QuickSort Sorts the entire array +10. [`QuickSortRange`](./sort/quicksort.go#L24): QuickSortRange Sorts the specified range within the array +11. [`RadixSort`](./sort/radixsort.go#L35): No description provided. +12. [`SelectionSort`](./sort/selectionsort.go#L3): No description provided. +13. [`ShellSort`](./sort/shellsort.go#L3): No description provided. +14. [`SimpleSort`](./sort/simplesort.go#L11): No description provided. --- ##### Types