Skip to content

algorithm: bucketsort and pancakesort #606

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 20 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -867,24 +867,26 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.
##### Functions:

1. [`Bubble`](./sort/bubblesort.go#L9): Bubble is a simple generic definition of Bubble sort algorithm.
2. [`Comb`](./sort/combSort.go#L17): Comb is a simple sorting algorithm which is an improvement of the bubble sorting algorithm.
3. [`Count`](./sort/countingsort.go#L11): No description provided.
4. [`Exchange`](./sort/exchangesort.go#L8): No description provided.
5. [`HeapSort`](./sort/heapsort.go#L116): No description provided.
6. [`ImprovedSimple`](./sort/simplesort.go#L27): ImprovedSimple 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
7. [`Insertion`](./sort/insertionsort.go#L5): No description provided.
8. [`Merge`](./sort/mergesort.go#L41): Merge Perform merge sort on a slice
9. [`MergeIter`](./sort/mergesort.go#L55): No description provided.
10. [`ParallelMerge`](./sort/mergesort.go#L66): ParallelMerge Perform merge sort on a slice using goroutines
11. [`Partition`](./sort/quicksort.go#L12): No description provided.
12. [`Patience`](./sort/patiencesort.go#L13): No description provided.
13. [`Pigeonhole`](./sort/pigeonholesort.go#L15): Pigeonhole sorts a slice using pigeonhole sorting algorithm. NOTE: To maintain time complexity O(n + N), this is the reason for having only Integer constraint instead of Ordered.
14. [`Quicksort`](./sort/quicksort.go#L39): Quicksort Sorts the entire array
15. [`QuicksortRange`](./sort/quicksort.go#L26): QuicksortRange Sorts the specified range within the array
16. [`RadixSort`](./sort/radixsort.go#L43): No description provided.
17. [`Selection`](./sort/selectionsort.go#L5): No description provided.
18. [`Shell`](./sort/shellsort.go#L5): No description provided.
19. [`Simple`](./sort/simplesort.go#L13): No description provided.
2. [`Bucket Sort`](./sort/bucketsort.go#L5): Bucket Sort works with the idea of distributing the elements of an array into a number of buckets. Each bucket is then sorted individually, either using a different sorting algorithm, or by recursively applying the bucket sorting algorithm.
3. [`Comb`](./sort/combSort.go#L17): Comb is a simple sorting algorithm which is an improvement of the bubble sorting algorithm.
4. [`Count`](./sort/countingsort.go#L11): No description provided.
5. [`Exchange`](./sort/exchangesort.go#L8): No description provided.
6. [`HeapSort`](./sort/heapsort.go#L116): No description provided.
7. [`ImprovedSimple`](./sort/simplesort.go#L27): ImprovedSimple 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
8. [`Insertion`](./sort/insertionsort.go#L5): No description provided.
9. [`Merge`](./sort/mergesort.go#L41): Merge Perform merge sort on a slice
10. [`MergeIter`](./sort/mergesort.go#L55): No description provided.
11. [`Pancake Sort`](./sort/pancakesort.go#L7): Pancake Sort is a sorting algorithm that is similar to selection sort that reverses elements of an array. The Pancake Sort uses the flip operation to sort the array.
12. [`ParallelMerge`](./sort/mergesort.go#L66): ParallelMerge Perform merge sort on a slice using goroutines
13. [`Partition`](./sort/quicksort.go#L12): No description provided.
14. [`Patience`](./sort/patiencesort.go#L13): No description provided.
15. [`Pigeonhole`](./sort/pigeonholesort.go#L15): Pigeonhole sorts a slice using pigeonhole sorting algorithm. NOTE: To maintain time complexity O(n + N), this is the reason for having only Integer constraint instead of Ordered.
16. [`Quicksort`](./sort/quicksort.go#L39): Quicksort Sorts the entire array
17. [`QuicksortRange`](./sort/quicksort.go#L26): QuicksortRange Sorts the specified range within the array
18. [`RadixSort`](./sort/radixsort.go#L43): No description provided.
19. [`Selection`](./sort/selectionsort.go#L5): No description provided.
20. [`Shell`](./sort/shellsort.go#L5): No description provided.
21. [`Simple`](./sort/simplesort.go#L13): No description provided.

---
##### Types
Expand Down
46 changes: 46 additions & 0 deletions sort/bucketsort.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package sort

import "github.com/TheAlgorithms/Go/constraints"

// Bucket sorts a slice. It is mainly useful
// when input is uniformly distributed over a range.
func Bucket[T constraints.Number](arr []T) []T {
// early return if the array too small
if len(arr) <= 1 {
return arr
}

// find the maximum and minimum elements in arr
max := arr[0]
min := arr[0]
for _, v := range arr {
if v > max {
max = v
}
if v < min {
min = v
}
}

// create an empty bucket for each element in arr
bucket := make([][]T, len(arr))

// put each element in the appropriate bucket
for _, v := range arr {
bucketIndex := int((v - min) / (max - min) * T(len(arr)-1))
bucket[bucketIndex] = append(bucket[bucketIndex], v)
}

// use insertion sort to sort each bucket
for i := range bucket {
bucket[i] = Insertion(bucket[i])
}

// concatenate the sorted buckets
sorted := make([]T, 0, len(arr))
for _, v := range bucket {
sorted = append(sorted, v...)
}

return sorted
}
44 changes: 44 additions & 0 deletions sort/pancakesort.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package sort

import "github.com/TheAlgorithms/Go/constraints"

// Pancake sorts a slice using flip operations,
// where flip refers to the idea of reversing the
// slice from index `0` to `i`.
func Pancake[T constraints.Ordered](arr []T) []T {
// early return if the array too small
if len(arr) <= 1 {
return arr
}

// start from the end of the array
for i := len(arr) - 1; i > 0; i-- {
// find the index of the maximum element in arr
max := 0
for j := 1; j <= i; j++ {
if arr[j] > arr[max] {
max = j
}
}

// if the maximum element is not at the end of the array
if max != i {
// flip the maximum element to the beginning of the array
arr = flip(arr, max)

// flip the maximum element to the end of the array by flipping the whole array
arr = flip(arr, i)
}
}

return arr
}

// flip reverses the input slice from `0` to `i`.
func flip[T constraints.Ordered](arr []T, i int) []T {
for j := 0; j < i; j++ {
arr[j], arr[i] = arr[i], arr[j]
i--
}
return arr
}
16 changes: 16 additions & 0 deletions sort/sorts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ func TestBubble(t *testing.T) {
testFramework(t, sort.Bubble[int])
}

func TestBucketSort(t *testing.T) {
testFramework(t, sort.Bucket[int])
}

func TestExchange(t *testing.T) {
testFramework(t, sort.Exchange[int])
}
Expand Down Expand Up @@ -153,6 +157,10 @@ func TestComb(t *testing.T) {
testFramework(t, sort.Comb[int])
}

func TestPancakeSort(t *testing.T) {
testFramework(t, sort.Pancake[int])
}

func TestPigeonhole(t *testing.T) {
testFramework(t, sort.Pigeonhole[int])
}
Expand Down Expand Up @@ -206,6 +214,10 @@ func BenchmarkBubble(b *testing.B) {
benchmarkFramework(b, sort.Bubble[int])
}

func BenchmarkBucketSort(b *testing.B) {
benchmarkFramework(b, sort.Bucket[int])
}

func BenchmarkExchange(b *testing.B) {
benchmarkFramework(b, sort.Exchange[int])
}
Expand Down Expand Up @@ -263,6 +275,10 @@ func BenchmarkComb(b *testing.B) {
benchmarkFramework(b, sort.Comb[int])
}

func BenchmarkPancakeSort(b *testing.B) {
benchmarkFramework(b, sort.Pancake[int])
}

func BenchmarkPigeonhole(b *testing.B) {
benchmarkFramework(b, sort.Pigeonhole[int])
}
Expand Down