幾天前,我在 Code Review 網(wǎng)站上發(fā)布了這個(gè)主題。在其中,我詳細(xì)介紹了我在合并排序代碼中實(shí)現(xiàn) goroutine 的第一次嘗試,雖然它運(yùn)行良好,但我希望有更好的實(shí)現(xiàn)。當(dāng)我想得更多時(shí),我有了一個(gè)我認(rèn)為可靠的想法:與其在將兩側(cè)合并在一起之前不斷等待左側(cè)和右側(cè)都完成,為什么不采用從左側(cè),因?yàn)樗趯?duì)自己進(jìn)行排序,并對(duì)從右側(cè)獲得的單個(gè)塊進(jìn)行排序,然后對(duì)它們進(jìn)行排序?我嘗試重組我的代碼,但遇到了一些問題:據(jù)我所知,我對(duì)基本情況的實(shí)現(xiàn)導(dǎo)致了巨大的問題,或者我誤解了 goroutine 的范圍,并告訴通道在何時(shí)關(guān)閉它們?cè)诓煌呐判驂K中仍在使用。我希望有人可以幫助我完善我的理解,或者,如果我的代碼以簡單的方式被破壞,幫助我理解我將在此代碼之后提出的問題: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? ? ? ? }? ? }總的來說,我最大的問題是,假設(shè)我們有以下類型:如果我當(dāng)前正在處理“38”和“27”配對(duì),并且關(guān)閉該 ms 通道,我希望它與在 main 中啟動(dòng)所有內(nèi)容的通道不是同一個(gè)通道?如果沒有,有沒有辦法可以在保留名稱的同時(shí)遞歸創(chuàng)建新頻道?希望這一切都有意義并感謝您的幫助。
1 回答

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