共计 2389 个字符,预计需要花费 6 分钟才能阅读完成。
博客:cbb777.fun
全平台账号: 安妮的心动录
github: https://github.com/anneheartrecord
下文中我说的可能对,也可能不对,鉴于笔者程度无限,请君自辨。有问题欢送大家找我探讨
手搓快排
须要留神的点有两个
1. 循环里两数替换的条件为 i < j 意味着左指针还在右指针的左侧 即两者还没相遇
2. 递归的时候一个是 j 一个是 j +1 把数组一分为二进行递归
func main() {nums := []int{3, 1, 2, 4, 6, 5}
quickSort(nums, 0, len(nums)-1)
fmt.Println(nums)
}
func quickSort(nums []int, l, r int) {
if l >= r {return}
i, j, mid := l-1, r+1, nums[(l+r)/2]
for i < j {
i++
for nums[i] < mid {i++}
j--
for nums[j] > mid {j--}
if i < j {nums[i], nums[j] = nums[j], nums[i]
}
}
quickSort(nums, l, j)
quickSort(nums, j+1, r)
}
手搓堆排
须要留神的点:
1.heapify 用来递归做调整 其中 heapSize 示意堆大小 i 示意要操作的节点下标 left 和 right 的值别离是 2i+1 与 2i+2
2.buildHeap 和 heapify 都传参都是 i,n,而堆排的时候是保护一个以后大小的堆,所以是 0,i
func main() {nums := []int{3, 1, 2, 4, 6, 5}
heapSort(nums)
fmt.Println(nums)
}
func buildHeap(nums []int, heapSize int) {
for i := heapSize / 2; i >= 0; i-- {heapify(nums, i, heapSize)
}
}
func heapSort(nums []int) {heapSize := len(nums)
buildHeap(nums, heapSize)
for i := heapSize - 1; i >= 0; i-- {nums[i], nums[0] = nums[0], nums[i]
heapify(nums, 0, i)
}
}
func heapify(nums []int, i, heapSize int) {
largest := i
left, right := 2*i+1, 2*i+2
if left < heapSize && nums[left] > nums[largest] {largest = left}
if right < heapSize && nums[right] > nums[largest] {largest = right}
if largest != i {nums[largest], nums[i] = nums[i], nums[largest]
heapify(nums, largest, heapSize)
}
}
实现一个生产者 - 消费者模型
要留神的就是
通过 select 来实现一有音讯就读,如果读完就退出
那怎么判断是否读完呢?这里就须要生产者被动敞开 channel 了
func main() {ch := make(chan int,10)
go Processor(ch)
go Consumer(ch)
// 睡一会
time.Sleep(15 * time.Second)
}
func Processor(ch chan int) {
for i := 0; i < 10; i++ {
ch <- i
// 模仿发工夫的时延 这里可有可无
//time.Sleep(1 * time.Second)
fmt.Println("process:", i)
}
close(ch)
}
func Consumer(ch chan int) {
for {
select {
// 有数据就读进去 敞开了就退出
case i, ok := <-ch:
if ok {fmt.Println("consumer:", i)
} else {fmt.Println("over!")
return
}
}
}
}
实现两个 goroutine 打印奇偶数
须要留神的点是
敞开通道的时候须要异步进行,也就是异步 Wait(),而后立马关掉 ch
同步的话会有一个问题就是 Even 和 Odd 都往这个 ch 中写货色了,然而没有人去生产它,所以咱们只能抉择手动敞开。然而期待 for range 结束,而后同步敞开的话会导致 ch 阻塞(因为 for range 不是生产)
func Even(wg *sync.WaitGroup, ch chan int) {defer wg.Done()
for i := 0; i <= 100; i += 2 {ch <- i}
}
func Odd(wg *sync.WaitGroup, ch chan int) {defer wg.Done()
for i := 1; i <= 100; i += 2 {ch <- i}
}
func main() {
var wg sync.WaitGroup
ch := make(chan int)
wg.Add(2)
go Even(&wg, ch)
go Odd(&wg, ch)
go func() {wg.Wait()
close(ch)
}()
for v := range ch {fmt.Println("number:", v)
}
}
实现两个 goroutine 交替打印奇偶数
须要留神的点:
通道必须得是有缓冲的,不然在 main goroutine 中往里面 <- 1 就会阻塞住,上面的 go 协程就不会执行了
func Even(ch chan int) {
for i := 0; i <= 100; i += 2 {
<-ch
fmt.Println("number:", i)
ch <- 1
}
}
func Odd(ch chan int) {
for i := 1; i <= 100; i += 2 {
<-ch
fmt.Println("number:", i)
ch <- 1
}
}
func main() {ch := make(chan int, 1)
ch <- 1
go Even(ch)
go Odd(ch)
time.Sleep(time.Second)
}
本文由 mdnice 多平台公布
正文完