generated from alura/modelo-vitrinedev
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmergesort.go
70 lines (55 loc) · 1.26 KB
/
mergesort.go
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
65
66
67
68
69
70
package sort
import "sync"
func MergeSort[T any](array []T, less func(T, T) bool) {
if len(array) <= 1 {
return
}
buffer := make([]T, len(array))
mergeSortRecursive(array, buffer, less)
}
func mergeSortRecursive[T any](array []T, buffer []T, less func(T, T) bool) {
length := len(array)
mid := length / 2
if length <= 1 {
return
}
if length > 100 {
var wg sync.WaitGroup
wg.Add(2)
go func(wgp *sync.WaitGroup) {
defer (*wgp).Done()
mergeSortRecursive(array[:mid], buffer[:mid], less)
}(&wg)
go func(wgp *sync.WaitGroup) {
defer (*wgp).Done()
mergeSortRecursive(array[mid:], buffer[mid:], less)
}(&wg)
wg.Wait()
} else {
mergeSortRecursive(array[:mid], buffer[:mid], less)
mergeSortRecursive(array[mid:], buffer[mid:], less)
}
mergeSortedArrays(array[:mid], array[mid:], buffer, less)
copy(array, buffer)
}
func mergeSortedArrays[T any](array1 []T, array2 []T, buffer []T, less func(T, T) bool) {
var i1, i2, i3 int
for i1 < len(array1) && i2 < len(array2) {
if less(array2[i2], array1[i1]) {
buffer[i3] = array2[i2]
i2++
} else {
buffer[i3] = array1[i1]
i1++
}
i3++
}
if i1 < len(array1) {
copy(buffer[i3:], array1[i1:])
return
}
if i2 < len(array2) {
copy(buffer[i3:], array2[i2:])
return
}
}