使用併發合併排序對整數切片進行排序的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.