Skip to content

Commit c027418

Browse files
authored
algorithm: bucketsort and pancakesort (#606)
1 parent d21128e commit c027418

File tree

4 files changed

+126
-18
lines changed

4 files changed

+126
-18
lines changed

README.md

+20-18
Original file line numberDiff line numberDiff line change
@@ -867,24 +867,26 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.
867867
##### Functions:
868868

869869
1. [`Bubble`](./sort/bubblesort.go#L9): Bubble is a simple generic definition of Bubble sort algorithm.
870-
2. [`Comb`](./sort/combSort.go#L17): Comb is a simple sorting algorithm which is an improvement of the bubble sorting algorithm.
871-
3. [`Count`](./sort/countingsort.go#L11): No description provided.
872-
4. [`Exchange`](./sort/exchangesort.go#L8): No description provided.
873-
5. [`HeapSort`](./sort/heapsort.go#L116): No description provided.
874-
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
875-
7. [`Insertion`](./sort/insertionsort.go#L5): No description provided.
876-
8. [`Merge`](./sort/mergesort.go#L41): Merge Perform merge sort on a slice
877-
9. [`MergeIter`](./sort/mergesort.go#L55): No description provided.
878-
10. [`ParallelMerge`](./sort/mergesort.go#L66): ParallelMerge Perform merge sort on a slice using goroutines
879-
11. [`Partition`](./sort/quicksort.go#L12): No description provided.
880-
12. [`Patience`](./sort/patiencesort.go#L13): No description provided.
881-
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.
882-
14. [`Quicksort`](./sort/quicksort.go#L39): Quicksort Sorts the entire array
883-
15. [`QuicksortRange`](./sort/quicksort.go#L26): QuicksortRange Sorts the specified range within the array
884-
16. [`RadixSort`](./sort/radixsort.go#L43): No description provided.
885-
17. [`Selection`](./sort/selectionsort.go#L5): No description provided.
886-
18. [`Shell`](./sort/shellsort.go#L5): No description provided.
887-
19. [`Simple`](./sort/simplesort.go#L13): No description provided.
870+
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.
871+
3. [`Comb`](./sort/combSort.go#L17): Comb is a simple sorting algorithm which is an improvement of the bubble sorting algorithm.
872+
4. [`Count`](./sort/countingsort.go#L11): No description provided.
873+
5. [`Exchange`](./sort/exchangesort.go#L8): No description provided.
874+
6. [`HeapSort`](./sort/heapsort.go#L116): No description provided.
875+
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
876+
8. [`Insertion`](./sort/insertionsort.go#L5): No description provided.
877+
9. [`Merge`](./sort/mergesort.go#L41): Merge Perform merge sort on a slice
878+
10. [`MergeIter`](./sort/mergesort.go#L55): No description provided.
879+
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.
880+
12. [`ParallelMerge`](./sort/mergesort.go#L66): ParallelMerge Perform merge sort on a slice using goroutines
881+
13. [`Partition`](./sort/quicksort.go#L12): No description provided.
882+
14. [`Patience`](./sort/patiencesort.go#L13): No description provided.
883+
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.
884+
16. [`Quicksort`](./sort/quicksort.go#L39): Quicksort Sorts the entire array
885+
17. [`QuicksortRange`](./sort/quicksort.go#L26): QuicksortRange Sorts the specified range within the array
886+
18. [`RadixSort`](./sort/radixsort.go#L43): No description provided.
887+
19. [`Selection`](./sort/selectionsort.go#L5): No description provided.
888+
20. [`Shell`](./sort/shellsort.go#L5): No description provided.
889+
21. [`Simple`](./sort/simplesort.go#L13): No description provided.
888890

889891
---
890892
##### Types

sort/bucketsort.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package sort
2+
3+
import "github.com/TheAlgorithms/Go/constraints"
4+
5+
// Bucket sorts a slice. It is mainly useful
6+
// when input is uniformly distributed over a range.
7+
func Bucket[T constraints.Number](arr []T) []T {
8+
// early return if the array too small
9+
if len(arr) <= 1 {
10+
return arr
11+
}
12+
13+
// find the maximum and minimum elements in arr
14+
max := arr[0]
15+
min := arr[0]
16+
for _, v := range arr {
17+
if v > max {
18+
max = v
19+
}
20+
if v < min {
21+
min = v
22+
}
23+
}
24+
25+
// create an empty bucket for each element in arr
26+
bucket := make([][]T, len(arr))
27+
28+
// put each element in the appropriate bucket
29+
for _, v := range arr {
30+
bucketIndex := int((v - min) / (max - min) * T(len(arr)-1))
31+
bucket[bucketIndex] = append(bucket[bucketIndex], v)
32+
}
33+
34+
// use insertion sort to sort each bucket
35+
for i := range bucket {
36+
bucket[i] = Insertion(bucket[i])
37+
}
38+
39+
// concatenate the sorted buckets
40+
sorted := make([]T, 0, len(arr))
41+
for _, v := range bucket {
42+
sorted = append(sorted, v...)
43+
}
44+
45+
return sorted
46+
}

sort/pancakesort.go

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package sort
2+
3+
import "github.com/TheAlgorithms/Go/constraints"
4+
5+
// Pancake sorts a slice using flip operations,
6+
// where flip refers to the idea of reversing the
7+
// slice from index `0` to `i`.
8+
func Pancake[T constraints.Ordered](arr []T) []T {
9+
// early return if the array too small
10+
if len(arr) <= 1 {
11+
return arr
12+
}
13+
14+
// start from the end of the array
15+
for i := len(arr) - 1; i > 0; i-- {
16+
// find the index of the maximum element in arr
17+
max := 0
18+
for j := 1; j <= i; j++ {
19+
if arr[j] > arr[max] {
20+
max = j
21+
}
22+
}
23+
24+
// if the maximum element is not at the end of the array
25+
if max != i {
26+
// flip the maximum element to the beginning of the array
27+
arr = flip(arr, max)
28+
29+
// flip the maximum element to the end of the array by flipping the whole array
30+
arr = flip(arr, i)
31+
}
32+
}
33+
34+
return arr
35+
}
36+
37+
// flip reverses the input slice from `0` to `i`.
38+
func flip[T constraints.Ordered](arr []T, i int) []T {
39+
for j := 0; j < i; j++ {
40+
arr[j], arr[i] = arr[i], arr[j]
41+
i--
42+
}
43+
return arr
44+
}

sort/sorts_test.go

+16
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ func TestBubble(t *testing.T) {
8181
testFramework(t, sort.Bubble[int])
8282
}
8383

84+
func TestBucketSort(t *testing.T) {
85+
testFramework(t, sort.Bucket[int])
86+
}
87+
8488
func TestExchange(t *testing.T) {
8589
testFramework(t, sort.Exchange[int])
8690
}
@@ -153,6 +157,10 @@ func TestComb(t *testing.T) {
153157
testFramework(t, sort.Comb[int])
154158
}
155159

160+
func TestPancakeSort(t *testing.T) {
161+
testFramework(t, sort.Pancake[int])
162+
}
163+
156164
func TestPigeonhole(t *testing.T) {
157165
testFramework(t, sort.Pigeonhole[int])
158166
}
@@ -206,6 +214,10 @@ func BenchmarkBubble(b *testing.B) {
206214
benchmarkFramework(b, sort.Bubble[int])
207215
}
208216

217+
func BenchmarkBucketSort(b *testing.B) {
218+
benchmarkFramework(b, sort.Bucket[int])
219+
}
220+
209221
func BenchmarkExchange(b *testing.B) {
210222
benchmarkFramework(b, sort.Exchange[int])
211223
}
@@ -263,6 +275,10 @@ func BenchmarkComb(b *testing.B) {
263275
benchmarkFramework(b, sort.Comb[int])
264276
}
265277

278+
func BenchmarkPancakeSort(b *testing.B) {
279+
benchmarkFramework(b, sort.Pancake[int])
280+
}
281+
266282
func BenchmarkPigeonhole(b *testing.B) {
267283
benchmarkFramework(b, sort.Pigeonhole[int])
268284
}

0 commit comments

Comments
 (0)