Skip to content

Instantly share code, notes, and snippets.

@ncw
Created March 10, 2015 09:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ncw/5419af0e255d2fb62b98 to your computer and use it in GitHub Desktop.
Save ncw/5419af0e255d2fb62b98 to your computer and use it in GitHub Desktop.
A channel based quicksort.
// Channel based quicksort
//
// Just for fun!
//
// Interesting that you can make a quicksort without being able to
// index your input. It may be O(n log n) for comparisons but it is
// O(n) for channels and go routines so perhaps not the most efficient
// quicksort ever ;-)
//
// It also has the worst case complexity O(n²) if you feed it sorted
// input, so don't do that!
//
// Originally from: https://plus.google.com/103015172458796488244/posts/TNCvNEBdjEt
// Plaground: http://play.golang.org/p/3eR_3wCq5X
package main
import (
"fmt"
"math/rand"
)
// Quicksort in to out
//
// Caller must close in when finished
// Quicksort will close out when finished
func quicksort(in, out chan int) {
defer close(out)
pivot, ok := <-in
// Finish recursion if no input - is sorted
if !ok {
return
}
// Divide and conquer the problem
left_in := make(chan int)
left_out := make(chan int)
go quicksort(left_in, left_out)
right_in := make(chan int)
right_out := make(chan int)
go quicksort(right_in, right_out)
// Feed the two halves
go func() {
for i := range in {
if i < pivot {
left_in <- i
} else {
right_in <- i
}
}
close(left_in)
close(right_in)
}()
// Join the sorted streams
for i := range left_out {
out <- i
}
out <- pivot
for i := range right_out {
out <- i
}
}
func main() {
in := make(chan int)
out := make(chan int)
go quicksort(in, out)
for i := 0; i < 100; i++ {
in <- rand.Intn(1000)
}
close(in)
for i := range out {
fmt.Println(i)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment