forked from steger/pr3-sose2026
merge sort
parent
2d1eec66ea
commit
ff4a4b2023
|
|
@ -4,9 +4,108 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sort"
|
"sort"
|
||||||
|
"sync"
|
||||||
"time"
|
"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) {
|
func mergeSortSequential(data []float64) {
|
||||||
if len(data) <= 1 {
|
if len(data) <= 1 {
|
||||||
return
|
return
|
||||||
|
|
@ -45,7 +144,7 @@ func merge(left, right []float64) []float64 {
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
//1. DATA CREATION
|
//1. DATA CREATION
|
||||||
data := make([]float64, 1000*1000*20)
|
data := make([]float64, 1000*1000*20) //*1000*20)
|
||||||
|
|
||||||
for i := range data {
|
for i := range data {
|
||||||
data[i] = rand.Float64() * 100 // Random floats between 0 and 100
|
data[i] = rand.Float64() * 100 // Random floats between 0 and 100
|
||||||
|
|
@ -58,7 +157,9 @@ func main() {
|
||||||
//2. SORTING
|
//2. SORTING
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
mergeSortSequential(data)
|
//mergeSortSequential(data)
|
||||||
|
//mergeSortParallel(data)
|
||||||
|
mergeSortChannels(data)
|
||||||
|
|
||||||
elapsed := time.Since(start)
|
elapsed := time.Since(start)
|
||||||
fmt.Printf("MergeSort took %s\n", elapsed)
|
fmt.Printf("MergeSort took %s\n", elapsed)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue