使用go语言的go关键字以及通道机制实现的一个玩具快速排序,仅为个人熟悉go的并发而写的,不具有实际使用价值。想要有实际使用的价值的话应使用接口适应不同的数据类型,分割点的选择也应该使用三点取中或者随机化的方式,在递归到数据量较小时(比如n <= 16)应该改用插入排序。
//以最后一个元素为分割点进行分割
func partition(arr []int, low, high int) int {
    for j := low; j < high - 1; j++ {
        if arr[j] < arr[high - 1] {
            arr[low], arr[j] = arr[j], arr[low]
            low++
        }
    }
    arr[low], arr[high - 1] = arr[high - 1], arr[low]
    return low
}

//将arr的[low, high)区间进行排序,done用于发送排序完成的信号,如果在原先的goroutine中进行则无需通信,置为nil即可。
func doSort(arr []int, low, high int, done chan<- struct{}) {
    if high - low > 1 {
        p := partition(arr, low, high)
        c := make(chan struct{})
        go doSort(arr, low, p, c) //左半区间的工作分配给一个新的goroutine并发进行
        doSort(arr, p + 1, high, nil) //右半区间的工作直接在当前的goroutine中进行
        <-c //等待左半区间的工作完成
    }
    if done != nil {
        done<- struct{}{} //发送一个信号告知本区间的工作完成
    }
}

func Sort(arr []int) {
    doSort(arr, 0, len(arr), nil)
}