forked from steger/pr3-sose2026
merge sort
parent
2d1eec66ea
commit
ff4a4b2023
|
|
@ -4,9 +4,108 @@ import (
|
|||
"fmt"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
func mergeSortChannelsInternal(data []float64, sorted chan<- float64) {
|
||||
defer close(sorted)
|
||||
|
||||
if len(data) <= 10000 {
|
||||
sortedData := make([]float64, len(data))
|
||||
copy(sortedData, data)
|
||||
mergeSortSequential(sortedData)
|
||||
for _, x := range sortedData {
|
||||
sorted <- x
|
||||
}
|
||||
} else {
|
||||
mid := len(data) / 2
|
||||
left := data[:mid]
|
||||
right := data[mid:]
|
||||
|
||||
sortedLeft := make(chan float64, 1000)
|
||||
sortedRight := make(chan float64, 1000)
|
||||
|
||||
go mergeSortChannelsInternal(left, sortedLeft)
|
||||
go mergeSortChannelsInternal(right, sortedRight)
|
||||
mergeChannels(sortedLeft, sortedRight, sorted)
|
||||
}
|
||||
}
|
||||
|
||||
func mergeChannels(a, b <-chan float64, out chan<- float64) {
|
||||
var okA, okB bool
|
||||
var valA, valB float64
|
||||
|
||||
for {
|
||||
if !okA {
|
||||
valA, okA = <-a
|
||||
}
|
||||
|
||||
if !okB {
|
||||
valB, okB = <-b
|
||||
}
|
||||
|
||||
if !okA && !okB {
|
||||
break
|
||||
}
|
||||
|
||||
if !okA {
|
||||
out <- valB
|
||||
okB = false
|
||||
continue
|
||||
}
|
||||
|
||||
if !okB {
|
||||
out <- valA
|
||||
okA = false
|
||||
continue
|
||||
}
|
||||
|
||||
if valA < valB {
|
||||
out <- valA
|
||||
okA = false
|
||||
} else {
|
||||
out <- valB
|
||||
okB = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mergeSortChannels(data []float64) {
|
||||
sorted := make(chan float64, 1000)
|
||||
go mergeSortChannelsInternal(data, sorted)
|
||||
|
||||
sortedData := make([]float64, len(data))
|
||||
i := 0
|
||||
for x := range sorted {
|
||||
sortedData[i] = x
|
||||
i++
|
||||
}
|
||||
|
||||
copy(data, sortedData)
|
||||
}
|
||||
|
||||
func mergeSortParallel(data []float64) {
|
||||
if len(data) <= 10000 {
|
||||
mergeSortSequential(data)
|
||||
return
|
||||
}
|
||||
|
||||
mid := len(data) / 2
|
||||
left := data[:mid]
|
||||
right := data[mid:]
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
|
||||
go func() { mergeSortParallel(left); wg.Done() }()
|
||||
go func() { mergeSortParallel(right); wg.Done() }()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
copy(data, merge(left, right))
|
||||
}
|
||||
|
||||
func mergeSortSequential(data []float64) {
|
||||
if len(data) <= 1 {
|
||||
return
|
||||
|
|
@ -45,7 +144,7 @@ func merge(left, right []float64) []float64 {
|
|||
func main() {
|
||||
|
||||
//1. DATA CREATION
|
||||
data := make([]float64, 1000*1000*20)
|
||||
data := make([]float64, 1000*1000*20) //*1000*20)
|
||||
|
||||
for i := range data {
|
||||
data[i] = rand.Float64() * 100 // Random floats between 0 and 100
|
||||
|
|
@ -58,7 +157,9 @@ func main() {
|
|||
//2. SORTING
|
||||
start := time.Now()
|
||||
|
||||
mergeSortSequential(data)
|
||||
//mergeSortSequential(data)
|
||||
//mergeSortParallel(data)
|
||||
mergeSortChannels(data)
|
||||
|
||||
elapsed := time.Since(start)
|
||||
fmt.Printf("MergeSort took %s\n", elapsed)
|
||||
|
|
|
|||
Loading…
Reference in New Issue