Go实现并发排序
来源:互联网 发布:淘宝网开通账户 编辑:程序博客网 时间:2024/05/29 04:51
前言
最近在学习Go语言,于是用go实现了两种排序的并发实现,下面我将一一进行介绍。
快排实现
下面先贴出快排代码:
func QuickSort(num []int, low, high int) { if low >= high { return } i, j := low, high key := num[low] for i < j { for j > i && num[j] >= key { j-- } num[i] = num[j] for i < j && num[i] < key { i++ } num[j] = num[i] } num[j] = key QuickSort(num, low, i-1) QuickSort(num, i+1, high)}
接着我们先贴出并发代码,再进行一些讨论
import "sync"func MutiQuickSort(num []int){ //如果缺少该句,由于下面第一次调用QuickSort,没有加一操作,执行完后直接lock.Done(),将导致数量减为-1而报错 lock.Add(1) QuickSort(num, 0, len(num)-1) lock.Wait()}var lock sync.WaitGroupfunc QuickSort(num []int, low, high int) { defer lock.Done() if low >= high { return } i, j := low, high key := num[low] for i < j { for j > i && num[j] >= key { j-- } num[i] = num[j] for i < j && num[i] < key { i++ } num[j] = num[i] } num[j] = key lock.Add(2) go QuickSort(num, low, i-1) go QuickSort(num, i+1, high)}
并发快排代码的思考
(1)为什么使用WaitGroup来实现? 因为快速排序对数组不断进行分割,最终使其完全有序。这里在考虑并发实现时,只需对其每次分割后的两部分 调用go启动协程进行实现,而这种并发情况下,主线程只需等待所有的排序携程都执行完成,即可实现并发排序。 [可参考下面的归并排序进行对比](2)关于WaitGroup的使用? //定义sync.WaitGroup变量(全局变量) var Lock sync.WaitGroup //主线程等待(等待数量减为0,主线程结束) Lock.Wait() //子协程开启时(数量加2) Lock.Add(2) //子协程完成时(数量减1) Lock.Done()
归并实现
我们仍然先来贴归并代码
func MergeSort(a []int, left, right int) { if left < right { mid := left + (right-left)/2 MergeSort(a, left, mid) MergeSort(a, mid+1, right) Merge(a, left, mid, right) }}func Merge(a []int, left, mid, right int) { arr := make([]int, 0) i, j := left, mid+1 for i <= mid && j <= right { if a[i] <= a[j] { arr = append(arr,a[i]) i++ } else { arr = append(arr,a[j]) j++ } } arr = append(arr, a[i:mid+1]...) arr = append(arr, a[j:right+1]...) for i, v := range arr { a[left+i] = v }}
接着是并发归并的代码
func MutiMergeSort(a []int) { ch := make(chan int, 1) defer close(ch) MergeSort(a, 0, len(a)-1, ch)}func MergeSort(a []int, left, right int, c chan int) { if left < right { ch := make(chan int, 2) defer close(ch) mid := left + (right-left)/2 go MergeSort(a, left, mid, ch) go MergeSort(a, mid+1, right, ch) <-ch <-ch Merge(a, left, mid, right) } c <- 1}func Merge(a []int, left, mid, right int) { arr := make([]int, 0) i, j := left, mid+1 for i <= mid && j <= right { if a[i] <= a[j] { arr = append(arr, a[i]) i++ } else { arr = append(arr, a[j]) j++ } } arr = append(arr, a[i:mid+1]...) arr = append(arr, a[j:right+1]...) for i, v := range arr { a[left+i] = v }}
思考
(1)这里为什么使用channel来实现? 首先,我们还是来分析归并排序。归并排序在将数组进行分割成单个元素之后,还要不断合并已经排好有序的数组段。 所以在合并时,就需要等待 执行这两个数组段排序的协程都完成,方可继续。否则,会出现错误。(2)channel的使用? //创建缓冲区大小为1024的int类型的channel c := make(chan int, 1024) //写入数据 c <- 1 //读出数据 ch := <- c
测试代码
Go本身提供了一套轻量级的测试框架。符合规则的测试代码会在运行测试时被自动识别并执行。
命名规则:以 “_test”结尾的go文件会被看作测试程序
import ( "testing" "fmt" "math/rand")func TestMergeSort(t *testing.T) { list := make([]int, 0) for i := 0; i < 1000000; i++ { v := rand.Int() % 100000 list = append(list, v) } MutiMergeSort(list) for _, v := range list { fmt.Print(v, " ") }}
阅读全文
0 0
- Go实现并发排序
- 睡眠排序--go实现
- Go实现位图排序
- Go实现堆排序
- go语言实现快速排序
- GO实现 快速排序算法
- Go实现快速排序算法
- Go语言实现拓扑排序
- go通过共享变量实现并发
- Go 并发
- go并发
- go-并发
- Go并发
- Go语言实现位图排序(bitmap)
- 归并排序及go语言实现
- 堆排序算法及go语言实现
- Go语句实现简单的冒泡排序
- 图解算法练习--选择排序(Go实现)
- 修改Ubuntu的aptget源为阿里源的方法
- 最速曲线时间
- 课后习题page101.pp3.4
- 1710--1804书单
- centos 能ping 通 ssh 无法连接
- Go实现并发排序
- 牛客笔试:丢失的三个数
- 图解Android系统的启动过程
- OpenCV-Python——图像金字塔
- MongodbTemplate的查询操作
- 10.5日常总结
- 前端实用工具及其js相关功能的类库总结
- 信号量处理相关函数
- 顺序表筛选数据的应用