-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from nickborysov/bitonic_sort
Add Bitonic sort sorting algorithm implementation
- Loading branch information
Showing
3 changed files
with
93 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
}) | ||
} | ||
} |