Skip to content

Commit

Permalink
Merge pull request #9 from nickborysov/bitonic_sort
Browse files Browse the repository at this point in the history
Add Bitonic sort sorting algorithm implementation
  • Loading branch information
ektagarg authored Oct 26, 2019
2 parents b15909e + 615faa3 commit 721e30b
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 0 deletions.
15 changes: 15 additions & 0 deletions array/sort/bitonic_sort/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Bitonic Sort

Bitonic sort is a parallel sorting algorithm which performs O(n2 log n) comparisons. Although, the number of comparisons are more than that in any other popular sorting algorithm, It performs better for the parallel implementation because elements are compared in predefined sequence which must not be depended upon the data being sorted. The predefined sequence is called Bitonic sequence.

### Algorithm
1. Form a Bitonic sequence from the given random sequence which we have formed in the above step. We can consider it as the first step in our procedure. After this step, we get a sequence whose first half is sorted in ascending order while second step is sorted in descending order.
2. Compare first element of first half with the first element of the second half, then second element of the first half with the second element of the second half and so on. Swap the elements if any element in the second half is found to be smaller.
3. After the above step, we got all the elements in the first half smaller than all the elements in the second half. The compare and swap results into the two sequences of n/2 length each. Repeat the process performed in the second step recursively onto every sequence until we get single sorted sequence of length n.

### Complexity
```
Worst Case Time Complexity: O(log 2 n)
Best Case Time Complexity: O(log 2 n)
Average Time Complexity: O(log 2 n)
```
35 changes: 35 additions & 0 deletions array/sort/bitonic_sort/bitonic_sort.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package sort

// BitonicSort sorts slice using parallel sorting algorithm,
// which performs O(n2 log n) comparisons.
//
// This sort works when size of input is power of 2.
//
func BitonicSort(array []int) {
bitonicSort(array, 0, len(array), true)
}

func bitonicSort(array []int, low, count int, d bool) {
if count < 2 {
return
}
k := count / 2
bitonicSort(array, low, k, true)
bitonicSort(array, low+k, k, false)
merge(array, low, count, d)
}

func merge(array []int, low, count int, d bool) {
if count < 2 {
return
}
k := count / 2
for i := 0; i < low+k; i++ {
if d != (array[i] > array[i+k]) {
continue
}
array[i], array[i+k] = array[i+k], array[i]
}
merge(array, low, k, d)
merge(array, low+k, k, d)
}
43 changes: 43 additions & 0 deletions array/sort/bitonic_sort/bitonic_sort_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package sort

import (
"math/rand"
"testing"
"time"

"github.com/stretchr/testify/require"
)

func init() {
rand.Seed(time.Now().UnixNano())
}

func Test_BitonicSort(t *testing.T) {
tt := []struct {
name string
array []int
expResult []int
}{
{
name: "test_simple",
array: []int{1, 10, 2, 3, 1, 23, 45, 21},
expResult: []int{1, 1, 2, 3, 10, 21, 23, 45},
},
{
name: "test_from_100_to_0",
array: []int{64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
expResult: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64},
},
{
name: "test_256_elements",
array: []int{464, 607, 524, 772, 925, 90, 141, 651, 555, 319, 741, 263, 600, 558, 676, 514, 61, 308, 641, 261, 332, 102, 302, 374, 797, 11, 98, 909, 206, 404, 187, 916, 686, 301, 188, 998, 361, 252, 662, 701, 254, 759, 513, 986, 250, 490, 419, 18, 379, 796, 650, 142, 919, 794, 170, 453, 705, 205, 138, 963, 198, 207, 163, 458, 52, 366, 926, 846, 884, 701, 530, 931, 203, 859, 899, 902, 848, 879, 475, 528, 469, 68, 781, 876, 46, 32, 51, 598, 149, 281, 312, 506, 609, 910, 584, 996, 651, 902, 627, 751, 694, 660, 546, 388, 804, 878, 505, 855, 614, 913, 260, 431, 95, 861, 177, 192, 396, 675, 597, 212, 519, 808, 180, 36, 430, 636, 907, 935, 196, 252, 37, 924, 711, 158, 81, 501, 274, 694, 771, 249, 129, 39, 711, 369, 257, 650, 195, 554, 940, 481, 640, 319, 799, 180, 231, 935, 808, 59, 510, 688, 494, 481, 51, 111, 481, 977, 128, 143, 156, 983, 428, 348, 677, 639, 147, 264, 430, 26, 282, 909, 462, 840, 227, 42, 936, 420, 398, 350, 75, 485, 276, 945, 826, 967, 452, 261, 445, 5, 387, 437, 232, 965, 679, 811, 389, 840, 131, 738, 677, 14, 722, 355, 907, 645, 387, 955, 977, 597, 804, 276, 607, 465, 520, 907, 72, 43, 162, 233, 431, 584, 409, 805, 581, 908, 593, 963, 600, 915, 784, 985, 688, 791, 791, 503, 13, 866, 540, 475, 84, 272, 742, 326, 456, 801, 384, 564},
expResult: []int{5, 11, 13, 14, 18, 26, 32, 36, 37, 39, 42, 43, 46, 51, 51, 52, 59, 61, 68, 72, 75, 81, 84, 90, 95, 98, 102, 111, 128, 129, 131, 138, 141, 142, 143, 147, 149, 156, 158, 162, 163, 170, 177, 180, 180, 187, 188, 192, 195, 196, 198, 203, 205, 206, 207, 212, 227, 231, 232, 233, 249, 250, 252, 252, 254, 257, 260, 261, 261, 263, 264, 272, 274, 276, 276, 281, 282, 301, 302, 308, 312, 319, 319, 326, 332, 348, 350, 355, 361, 366, 369, 374, 379, 384, 387, 387, 388, 389, 396, 398, 404, 409, 419, 420, 428, 430, 430, 431, 431, 437, 445, 452, 453, 456, 458, 462, 464, 465, 469, 475, 475, 481, 481, 481, 485, 490, 494, 501, 503, 505, 506, 510, 513, 514, 519, 520, 524, 528, 530, 540, 546, 554, 555, 558, 564, 581, 584, 584, 593, 597, 597, 598, 600, 600, 607, 607, 609, 614, 627, 636, 639, 640, 641, 645, 650, 650, 651, 651, 660, 662, 675, 676, 677, 677, 679, 686, 688, 688, 694, 694, 701, 701, 705, 711, 711, 722, 738, 741, 742, 751, 759, 771, 772, 781, 784, 791, 791, 794, 796, 797, 799, 801, 804, 804, 805, 808, 808, 811, 826, 840, 840, 846, 848, 855, 859, 861, 866, 876, 878, 879, 884, 899, 902, 902, 907, 907, 907, 908, 909, 909, 910, 913, 915, 916, 919, 924, 925, 926, 931, 935, 935, 936, 940, 945, 955, 963, 963, 965, 967, 977, 977, 983, 985, 986, 996, 998},
},
}
for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
BitonicSort(tc.array)
require.Equal(t, tc.expResult, tc.array)
})
}
}

0 comments on commit 721e30b

Please sign in to comment.