幾天前,我在 Code Review 網站上發布了這個主題。在其中,我詳細介紹了我在合并排序代碼中實現 goroutine 的第一次嘗試,雖然它運行良好,但我希望有更好的實現。當我想得更多時,我有了一個我認為可靠的想法:與其在將兩側合并在一起之前不斷等待左側和右側都完成,為什么不采用從左側,因為它正在對自己進行排序,并對從右側獲得的單個塊進行排序,然后對它們進行排序?我嘗試重組我的代碼,但遇到了一些問題:據我所知,我對基本情況的實現導致了巨大的問題,或者我誤解了 goroutine 的范圍,并告訴通道在何時關閉它們在不同的排序塊中仍在使用。我希望有人可以幫助我完善我的理解,或者,如果我的代碼以簡單的方式被破壞,幫助我理解我將在此代碼之后提出的問題:package mainimport (? ? "crypto/rand"? ? "fmt"? ? "os"? ? "strconv")var (? ? nums? ? []byte //The slice of numbers we want to sort? ? numVals int? ? = -1)//User can optionally add a parameter that determines how many random numbers will be sorted//If none are provided, 100 will be usedfunc main() {? ? if len(os.Args) >= 2 {? ? ? ? numVals, _ = strconv.Atoi(os.Args[1])? ? } else {? ? ? ? numVals = 2? ? }? ? nums = initSlice()? ? ms := make(chan byte)? ? go mergeSort(nums, ms)? ? pos := 0? ? for val := range ms {? ? ? ? nums[pos] = val? ? ? ? pos++? ? }? ? for _, value := range nums {? ? ? ? fmt.Printf("%d\n", value)? ? }}func initSlice() []byte {? ? vals := make([]byte, numVals)? ? _, err := rand.Read(vals)? ? if err != nil {? ? ? ? panic(err)? ? }? ? return vals}func mergeSort(arr []byte, ms chan byte) {? ? if len(arr) <= 1 {? ? ? ? if len(arr) == 1 { //base case? ? ? ? ? ? ms <- arr[0]? ? ? ? }? ? ? ? close(ms)? ? ? ? return? ? }? ? leftMS := make(chan byte)? ? go mergeSort(arr[:len(arr)/2], leftMS)? ? rightMS := make(chan byte)? ? go mergeSort(arr[len(arr)/2:], rightMS)? ? left, lOK := <-leftMS? ? right, rOK := <-rightMS? ? for lOK && rOK {? ? ? ? leftLeast := left <= right? ? ? ? if leftLeast {? ? ? ? ? ? ms <- left? ? ? ? ? ? left, lOK = <-leftMS? ? ? ? } else {? ? ? ? ? ? ms <- right? ? ? ? ? ? right, lOK = <-rightMS? ? ? ? }? ? }? ? if lOK {? ? ? ? ms <- left? ? ? ? for val := range leftMS {? ? ? ? ? ? ms <- val? ? ? ? }? ? }總的來說,我最大的問題是,假設我們有以下類型:如果我當前正在處理“38”和“27”配對,并且關閉該 ms 通道,我希望它與在 main 中啟動所有內容的通道不是同一個通道?如果沒有,有沒有辦法可以在保留名稱的同時遞歸創建新頻道?希望這一切都有意義并感謝您的幫助。
1 回答

Qyouu
TA貢獻1786條經驗 獲得超11個贊
您的頻道使用不是您的問題。你的程序有兩個問題。
首先,您必須將結果收集到主 goroutine 中的單獨數組中,否則,您將在排序時修改正在排序的數組。
二、這個塊:
} else { ms <- right right, lOK = <-rightMS
它應該是
right, rOK = <-rightMS
您正在設置lOK
,rightMS
而不是rOK
。
- 1 回答
- 0 關注
- 106 瀏覽
添加回答
舉報
0/150
提交
取消