Skip to content

Instantly share code, notes, and snippets.

@feyeleanor
Forked from elisehuard/gist:635097
Created October 19, 2010 21:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save feyeleanor/635164 to your computer and use it in GitHub Desktop.
Save feyeleanor/635164 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"os"
)
type request struct {
data []int
replyChannel chan []int
}
func append(lesser[]int, pivot int, greater[]int) []int {
newSlice := make([]int, (len(lesser) + len(greater) + 1))
copy(newSlice, lesser)
newSlice[len(lesser)] = pivot
copy(newSlice[len(lesser) + 1:], greater)
return newSlice
}
func sort(incoming *request) {
data := incoming.data
if len(data) <= 1 {
incoming.replyChannel <- data
return
}
pivot, _ := pivot(data)
lessReply, greaterReply := startListener(incoming, pivot) // create channels and listener
less, greater := partition(data)
// now sort the resulting sub arrays in 2 goroutines
go sort(&request{data: less, replyChannel: lessReply})
go sort(&request{data: greater, replyChannel: greaterReply})
}
func pivot(data []int) (pivot int, pivotIndex int) {
pivotIndex = len(data)/2
pivot = data[pivotIndex]
return pivot, pivotIndex
}
func partition(data []int) (less []int, greater []int) {
pivot, pivotIndex := pivot(data)
less = make([]int, len(data))
greater = make([]int, len(data)) //just to be on the safe side
lessIndex := 0
greaterIndex := 0
for i, v := range data {
switch {
case i == pivotIndex:
case v <= pivot:
less[lessIndex] = v
lessIndex++
case v > pivot:
greater[greaterIndex] = v
greaterIndex++
}
}
return less[:lessIndex], greater[:greaterIndex]
}
func startListener(result *request, pivot int) (lessReply chan []int, greaterReply chan []int) {
lessReply = make(chan []int)
greaterReply = make(chan []int)
go sortListener(lessReply, greaterReply, result, pivot)
return lessReply, greaterReply
}
func sortListener(lessReply chan []int, greaterReply chan []int, result *request, pivot int) {
result.replyChannel <- append(<-lessReply, pivot, <-greaterReply)
}
func main() {
data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
replyChannel := make(chan []int)
sort(&request{data: data, replyChannel: replyChannel})
fmt.Fprintf(os.Stderr,"sorted %s\n", <-replyChannel)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment