Golang 使用并发的归并排序算法对整数切片进行排序
在本文中,我们将编写使用并发的归并排序算法对整数切片进行排序的Go语言程序。这个过程使得程序的各个部分可以独立并行地运行,从而提高程序的效率。使用Go协程和通道来实现并发执行。
归并排序是一种分治算法,用于对未排序的数组或切片进行排序,它将输入切片分割为较小的子切片,分别递归地对它们进行排序,然后将它们合并为一个排序好的单一切片。
语法
func make ([] type, size, capacity)
在Go语言中,make函数用于创建数组/映射,它接受要创建的变量类型、大小和容量作为参数。
步骤
- 程序中导入main,fmt和sync包。
-
创建一个名为merge_integers的函数,该函数以left和right作为参数,这两个切片将被合并为一个排序后的切片。
-
在这一步中,创建一个名为output的切片,其长度为left和right切片长度的和。
-
然后,初始化两个变量i和j为0,它们表示左切片和右切片的索引。
-
在这一步中,使用for循环对整数切片进行排序。
-
比较左切片和右切片索引i和j处的元素,如果左边小于右边,则将较小的值分配给output[i+j]。
-
然后,如果较小的值小于右边,则增加索引i,如果右边小于左边,则增加索引j。
-
它继续这个过程,直到其中一个切片完全遍历完毕。
-
循环遍历后,可能会在左切片或右切片中留下一些元素,它们将使用if-else条件进行检查,并添加到结果切片中。
-
最后,它返回包含左切片和右切片中合并和排序元素的输出切片。
-
创建一个并发执行的归并排序函数,将nums作为参数传递,表示要排序的切片。
-
在这一步中,检查输入切片的长度是否小于或等于1,如果是,则直接返回输入切片,因为它已经是有序的。
-
然后,计算nums切片的中间索引,并将其赋值给mid变量。
-
在这一步中,创建两个空的切片,left和right,用来存储切片的左半部分和右半部分。
-
然后,使用sync.WaitGroup初始化一个并发的计数器,并使用Add方法将计数设置为2,因为将有两个go协程同时运行。
-
接下来,使用匿名函数创建两个go协程。
-
在第一个go协程中,通过递归调用merge Sort方法对nums[:mid]切片的左半部分进行排序,并将结果存储在left切片中。
-
在第二个go协程中,通过递归调用merge Sort方法对nums[mid:]切片的右半部分进行排序,并将结果存储在right切片中。
-
使用Wait方法等待go协程完成处理过程。
-
在go程完成并且Wait Group计数器达到0之后,使用merge函数合并排序后的左右切片,并返回输出。
-
创建一个main函数。
-
在main函数中,创建一个未排序的整数切片,并将其存储在切片变量中。
-
然后,调用merge Sort函数对该切片进行排序。
-
最后,使用fmt包中的Println函数将排序结果打印到控制台。
示例
在本示例中,我们将编写一个Go语言程序,使用Go程和管道以并发方式实现合并排序算法来对整数片段进行排序。
package main
import (
"fmt"
"sync"
)
func merge_integers(left, right []int) []int {
output := make([]int, len(left)+len(right))
i, j := 0, 0
for i < len(left) && j < len(right) {
if left[i] <= right[j] {
output[i+j] = left[i]
i++
} else {
output[i+j] = right[j]
j++
}
}
for i < len(left) {
output[i+j] = left[i]
i++
}
for j < len(right) {
output[i+j] = right[j]
j++
}
return output
}
func mergeSort(nums []int) []int {
if len(nums) <= 1 {
return nums
}
mid := len(nums) / 2
var left, right []int
var wg sync.WaitGroup
wg.Add(2)
go func() {
left = mergeSort(nums[:mid])
wg.Done()
}()
go func() {
right = mergeSort(nums[mid:])
wg.Done()
}()
wg.Wait()
return merge_integers(left, right)
}
func main() {
slice := []int{90, 50, 10, 30, 80, 40, 20, 70, 60}
fmt.Println("Unsorted:", slice)
sorted := mergeSort(slice)
fmt.Println("Sorted:", sorted)
}
输出
Unsorted: [90 50 10 30 80 40 20 70 60]
Sorted: [10 20 30 40 50 60 70 80 90]
结论
我们通过实现并发,并利用使用Go协程和通道的示例,编译并执行了使用归并排序对整数片段进行排序的程序。因此,该程序成功执行。