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()
}

 

posted @ 2020-07-20 10:34  杜争斌  阅读(240)  评论(0编辑  收藏  举报