使用并发合并排序对整数切片进行排序的Go语言程序


在本文中,我们将编写Go语言程序,使用并发合并排序对整数切片进行排序。这是一个使程序的部分独立并行运行的过程,从而提高程序效率。Go 协程和通道用于执行并发。

合并排序是一种分治算法,用于通过将输入切片划分为较小的子切片、递归地分别对它们进行排序,然后将它们合并成一个已排序的切片来对未排序的数组或切片进行排序。

语法

func make ([] type, size, capacity)

Go语言中的make函数用于创建数组/映射,它接受要创建的变量的类型、其大小和容量作为参数。

算法

  • 此程序在程序中导入main、fmt和sync包。

  • 创建一个名为merge_integers的函数,该函数接受两个切片left和right作为参数,这两个切片将合并成一个已排序的切片。

  • 在此步骤中,创建一个名为output的切片,其长度等于left和right切片长度的总和。

  • 然后,将两个变量i和j初始化为0,它们分别表示left和right切片的索引。

  • 在此步骤中,使用for循环对整数切片进行排序。

  • 比较left和right中索引i和j处的元素,如果left小于right,则将较小的值赋给output[i+j]。

  • 然后,如果less小于right则递增索引,如果right小于left则递增j。

  • 它继续此过程,直到其中一个切片完全遍历。

  • 遍历循环后,left或right切片中可能还剩下一些元素,稍后将使用if-else条件语句进行检查并添加到结果切片中。

  • 最后,它返回outputt切片,其中包含来自left和right的已合并和已排序的元素。

  • 创建一个merge Sort函数以使用nums作为参数执行并发,该参数表示要排序的切片。

  • 在此步骤中,检查如果输入切片的长度小于或等于1,则返回输入切片,因为它已经排序。

  • 然后,计算nums切片的中点索引并将其分配给mid变量。

  • 在此步骤中,创建两个空切片left和right,以存储切片的左右两半。

  • 然后,初始化一个sync.Wait Group并使用Add方法向其添加计数2,因为将有两个Go协程并发运行。

  • 然后,使用匿名函数创建两个Go协程。

  • 在第一个Go协程中,通过递归调用nums[:mid]上的merge Sort对nums的左半部分进行排序,并将输出存储在left切片中。

  • 在第二个Go协程中,通过递归调用nums[mid:]上的merge Sort对nums的右半部分进行排序,并将输出存储在right切片中。

  • 使用Wait方法等待Go协程完成处理。

  • Go协程完成后且Wait Group计数器达到0后,使用merge函数合并已排序的left和right切片,并返回输出。

  • 创建一个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协程和通道的示例实现了并发。因此,程序成功执行。

更新于: 2023年8月4日

203 次查看

开启你的 职业生涯

通过完成课程获得认证

立即开始
广告

© . All rights reserved.