go例子(四) 使用 goroutinue 进行排序
受使用 goroutinue 进行素数判断(主 goroutinue 进行循环添加数字到新创建的判断素数的 goroutinue 中,参考《golang 真正的高并发用法 查找素数》 )的启发,实现一个使用 goroutinue 进行 slice 排序
版本一:
思路:
1. 启动 len(data) -2 个协程,每个协程对比指定下标(从1到len(data) - 2 个)的值与前一个和后一个的进行判断,符合条件进行交换
2. 一次只能有一个 goroutinue 进行交换
3. 类似于 老师组织一次 排序游戏,每一次只能有一个同学进行交换。不需要判断,到一定时间久进化到排序状态了。
package main import ( "fmt" "math/rand" // "sync" "time" ) var size = 7 var data = []int{} //var want_change = make(chan bool,1) var can_change = make(chan bool,1) //var wg = sync.WaitGroup{} func main(){ for i := 0; i < size; i++ { data = append(data,rand.Intn(100)) } fmt.Println(data) //wg.Add(size) can_change <- true for i := 1; i < size - 1; i++ { go change(i) } //go printdata() printdata() //wg.Wait() } func printdata(){ exit := false for !exit { fmt.Println(data) exit = true for i := 0;i < size-1; i++ { if data[i] > data[i+1] { exit = false } } time.Sleep(time.Second) } } func change(i int) { for { select { case c,ok := <- can_change: { if !ok { can_change <- true continue } if c != true { can_change <- true continue } if data[i -1] > data [i] { data[i - 1],data[i] = data[i],data[i - 1] fmt.Printf("swap data[%d]:%d data[%d]%d\n",i-1,data[i-1],i,data[i]) fmt.Println("swap:",data) } if data[i] > data[i+1]{ data[i],data[i + 1] = data[i + 1],data[i] fmt.Printf("swap data[%d]:%d data[%d]%d\n",i,data[i],i+1,data[i+1]) fmt.Println("swap:",data) } can_change <- true } } } }
版本二:
思路:
1. 启动 len(data) -2 个协程,每个协程对比指定下标(从1到len(data) - 2 个)的值与前一个和后一个的进行判断,符合条件进行交换
2. 一次只能有一个 goroutinue 进行交换
3. 类似于 老师组织一次 排序游戏,每一次只能有一个同学进行交换,当大家都认为不需要再交换时就完成了排序。
package main import ( "fmt" "math/rand" "sync" ) var size = 7 var data = []int{} var canChangeChannel = make(chan bool,1) var wg = sync.WaitGroup{} func main(){ for i := 0; i < size; i++ { data = append(data,rand.Intn(100)) } fmt.Println(data) wg.Add(size-2) canChangeChannel <- true for i := 1; i < size - 1; i++ { go change(i) } wg.Wait() fmt.Println(data) } func change(i int) { exit := false for !exit { select { case c,ok := <- canChangeChannel: { if !ok { canChangeChannel <- true continue } if c != true { canChangeChannel <- true continue } exit = true for i := 0;i < size-1; i++ { if data[i] > data[i+1] { exit = false } } if data[i -1] > data [i] { data[i - 1],data[i] = data[i],data[i - 1] fmt.Printf("swap data[%d]:%d data[%d]%d\n",i-1,data[i-1],i,data[i]) fmt.Println("swap:",data) } if data[i] > data[i+1]{ data[i],data[i + 1] = data[i + 1],data[i] fmt.Printf("swap data[%d]:%d data[%d]%d\n",i,data[i],i+1,data[i+1]) fmt.Println("swap:",data) } canChangeChannel <- true } } } wg.Done() }
一法通,万法通,诸般深奥的学问到了极处,本是殊途同归。