From 6574504eedb64aeaa7176fccde0008086d20b875 Mon Sep 17 00:00:00 2001 From: Martmists Date: Tue, 9 Oct 2018 22:16:07 +0200 Subject: [PATCH] Add Stooge, pidgeonhole and cocktail shaker sort Signed-off-by: Martmists --- .editorconfig | 3 +- allalgorithms/.editorconfig | 3 +- allalgorithms/sorting/__init__.py | 3 ++ allalgorithms/sorting/cocktail_shaker_sort.py | 30 +++++++++++++++++++ allalgorithms/sorting/pidgeonhole_sort.py | 23 ++++++++++++++ allalgorithms/sorting/stooge_sort.py | 21 +++++++++++++ docs/sorting/cocktail-shaker-sort.md | 30 +++++++++++++++++++ docs/sorting/pidgeonhole-sort.md | 30 +++++++++++++++++++ docs/sorting/stooge-sort.md | 30 +++++++++++++++++++ tests/test_sorting.py | 21 ++++++++++--- 10 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 allalgorithms/sorting/cocktail_shaker_sort.py create mode 100644 allalgorithms/sorting/pidgeonhole_sort.py create mode 100644 allalgorithms/sorting/stooge_sort.py create mode 100644 docs/sorting/cocktail-shaker-sort.md create mode 100644 docs/sorting/pidgeonhole-sort.md create mode 100644 docs/sorting/stooge-sort.md diff --git a/.editorconfig b/.editorconfig index dec6b5b..4c3931a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,7 +8,8 @@ root = true [*] -indent_style = tab +indent_style = space +indent_size = 4 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true diff --git a/allalgorithms/.editorconfig b/allalgorithms/.editorconfig index 4d5a7f0..3e4ba08 100644 --- a/allalgorithms/.editorconfig +++ b/allalgorithms/.editorconfig @@ -7,7 +7,8 @@ root = true [*] -indent_style = tab +indent_style = space +indent_size = 4 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true diff --git a/allalgorithms/sorting/__init__.py b/allalgorithms/sorting/__init__.py index d84d4f4..f249576 100644 --- a/allalgorithms/sorting/__init__.py +++ b/allalgorithms/sorting/__init__.py @@ -2,3 +2,6 @@ from .insertion_sort import insertion_sort from .selection_sort import selection_sort from .bubble_sort import bubble_sort +from .pidgeonhole_sort import pidgeonhole_sort +from .stooge_sort import stooge_sort +from .cocktail_shaker_sort import cocktail_shaker_sort diff --git a/allalgorithms/sorting/cocktail_shaker_sort.py b/allalgorithms/sorting/cocktail_shaker_sort.py new file mode 100644 index 0000000..1a0252f --- /dev/null +++ b/allalgorithms/sorting/cocktail_shaker_sort.py @@ -0,0 +1,30 @@ +# -*- coding: UTF-8 -*- +# +# Cocktail Shaker Sort Algorithm +# The All ▲lgorithms library for python +# +# Contributed by: Martmists +# Github: @martmists +# + + +def cocktail_shaker_sort(data): + upper = len(data) - 1 + lower = 0 + + no_swap = False + while upper - lower > 1 and not no_swap: + no_swap = True + for j in range(lower, upper): + if data[j + 1] < data[j]: + data[j + 1], data[j] = data[j], data[j + 1] + no_swap = False + upper = upper - 1 + + for j in range(upper, lower, -1): + if data[j - 1] > data[j]: + data[j - 1], data[j] = data[j], data[j - 1] + no_swap = False + lower = lower + 1 + + return data diff --git a/allalgorithms/sorting/pidgeonhole_sort.py b/allalgorithms/sorting/pidgeonhole_sort.py new file mode 100644 index 0000000..aa0e709 --- /dev/null +++ b/allalgorithms/sorting/pidgeonhole_sort.py @@ -0,0 +1,23 @@ +# -*- coding: UTF-8 -*- +# +# Pidgeonhole Sort Algorithm +# The All ▲lgorithms library for python +# +# Contributed by: Martmists +# Github: @martmists +# + + +def pidgeonhole_sort(data): + minimum = min(data) + size = max(data) - minimum + 1 + holes = [0] * size + for item in data: + holes[item - minimum] += 1 + i = 0 + for count in range(size): + while holes[count] > 0: + holes[count] -= 1 + data[i] = count + minimum + i += 1 + return data diff --git a/allalgorithms/sorting/stooge_sort.py b/allalgorithms/sorting/stooge_sort.py new file mode 100644 index 0000000..499f8e6 --- /dev/null +++ b/allalgorithms/sorting/stooge_sort.py @@ -0,0 +1,21 @@ +# -*- coding: UTF-8 -*- +# +# Stooge Sort Algorithm +# The All ▲lgorithms library for python +# +# Contributed by: Martmists +# Github: @martmists +# + + +def stooge_sort(seq, start=0, end=None): + if end is None: + end = len(seq) - 1 + if seq[start] > seq[end]: + seq[start], seq[end] = seq[end], seq[start] + if (end - start + 1) > 2: + third = (end - start + 1) // 3 + stooge_sort(seq, start, end-third) + stooge_sort(seq, start+third, end) + stooge_sort(seq, start, end-third) + return seq diff --git a/docs/sorting/cocktail-shaker-sort.md b/docs/sorting/cocktail-shaker-sort.md new file mode 100644 index 0000000..8d8841c --- /dev/null +++ b/docs/sorting/cocktail-shaker-sort.md @@ -0,0 +1,30 @@ +# Cocktail Shaker Sort + +Cocktail shaker sort, also known as bidirectional bubble sort, cocktail sort, shaker sort (which can also refer to a variant of selection sort), ripple sort, shuffle sort, or shuttle sort, is a variation of bubble sort that is both a stable sorting algorithm and a comparison sort. The algorithm differs from a bubble sort in that it sorts in both directions on each pass through the list. This sorting algorithm is only marginally more difficult to implement than a bubble sort, and solves the problem of turtles in bubble sorts. It provides only marginal performance improvements, and does not improve asymptotic performance; like the bubble sort, it is not of practical interest (insertion sort is preferred for simple sorts), though it finds some use in education. + +## Install + +``` +pip install allalgorithms +``` + +## Usage + +```py +from allalgorithms.sorting import cocktail_shaker_sort + +arr = [77, 2, 10, -2, 1, 7] + +print(cocktail_shaker_sort(arr)) +# -> [-2, 1, 2, 7, 10, 77] +``` + +## API + +### cocktail_shaker_sort(array) + +> Returns a sorted array + +##### Params: + +- `array`: Unsorted Array diff --git a/docs/sorting/pidgeonhole-sort.md b/docs/sorting/pidgeonhole-sort.md new file mode 100644 index 0000000..8fa568e --- /dev/null +++ b/docs/sorting/pidgeonhole-sort.md @@ -0,0 +1,30 @@ +# Pidgeonhole Sort + +Pigeonhole sorting is a sorting algorithm that is suitable for sorting lists of elements where the number of elements (n) and the length of the range of possible key values (N) are approximately the same. It requires O(n + N) time. It is similar to counting sort, but differs in that it "moves items twice: once to the bucket array and again to the final destination [whereas] counting sort builds an auxiliary array then uses the array to compute each item's final destination and move the item there." + +## Install + +``` +pip install allalgorithms +``` + +## Usage + +```py +from allalgorithms.sorting import pidgeonhole_sort + +arr = [77, 2, 10, -2, 1, 7] + +print(pidgeonhole_sort(arr)) +# -> [-2, 1, 2, 7, 10, 77] +``` + +## API + +### pidgeonhole_sort(array) + +> Returns a sorted array + +##### Params: + +- `array`: Unsorted Array diff --git a/docs/sorting/stooge-sort.md b/docs/sorting/stooge-sort.md new file mode 100644 index 0000000..816fdea --- /dev/null +++ b/docs/sorting/stooge-sort.md @@ -0,0 +1,30 @@ +# Stooge Sort + +Stooge sort is a recursive sorting algorithm. It is notable for its exceptional bad time complexity of O(n^(log 3 / log 1.5)) = O(n^2.7095...). The running time of the algorithm is thus slower compared to reasonable sorting algorithms, and is slower than Bubble sort, a canonical example of a fairly inefficient sort. It is however more efficient than Slowsort. + +## Install + +``` +pip install allalgorithms +``` + +## Usage + +```py +from allalgorithms.sorting import stooge_sort + +arr = [77, 2, 10, -2, 1, 7] + +print(stooge_sort(arr)) +# -> [-2, 1, 2, 7, 10, 77] +``` + +## API + +### stooge_sort(array) + +> Returns a sorted array + +##### Params: + +- `array`: Unsorted Array diff --git a/tests/test_sorting.py b/tests/test_sorting.py index e11902b..7fe083c 100644 --- a/tests/test_sorting.py +++ b/tests/test_sorting.py @@ -1,12 +1,16 @@ import unittest from allalgorithms.sorting import ( - bubble_sort, - insertion_sort, - merge_sort, - selection_sort + bubble_sort, + insertion_sort, + merge_sort, + selection_sort, + pidgeonhole_sort, + stooge_sort, + cocktail_shaker_sort ) + class TestSorting(unittest.TestCase): def test_merge_sort(self): self.assertEqual([-44, 1, 2, 3, 7, 19], merge_sort([7, 3, 2, 19, -44, 1])) @@ -20,6 +24,15 @@ def test_insertion_sort(self): def test_selection_sort(self): self.assertEqual([-44, 1, 2, 3, 7, 19], selection_sort([7, 3, 2, 19, -44, 1])) + def test_pidgeonhole_sort(self): + self.assertEqual([-44, 1, 2, 3, 7, 19], pidgeonhole_sort([7, 3, 2, 19, -44, 1])) + + def test_stooge_sort(self): + self.assertEqual([-44, 1, 2, 3, 7, 19], stooge_sort([7, 3, 2, 19, -44, 1])) + + def test_cocktail_shaker_sort(self): + self.assertEqual([-44, 1, 2, 3, 7, 19], cocktail_shaker_sort([7, 3, 2, 19, -44, 1])) + if __name__ == "__main__": unittest.main()