猿问

同时计数树叶

我想使用并发模型来编写一个函数,以防输入太大而并行处理会更有效,但是它永远不会结束。


假设有一个struct定义为:


type Tree struct {

    Name     string   `json:"name"`

    SubTrees []*Tree  `json:"subTrees,omitempty"`

    Leaves   []string `json:"leaves"`

}

我想写一个函数来计算Leaves整个递归结构的总数。这很容易通过以下方式进行递归:


func (tree *Tree) CountLeaves() int {

    curr := len(tree.Leaves)

    for _, s := range tree.SubTrees {

        curr += s.CountLeaves()

    }

    return curr

}

很好,一切都很好,但是如果结构太大,效率将会很低,所以我想将其重构为并发并使用通道。这是我尝试进行重构的尝试:


func (tree *Tree) CountLeaves() int {

    var wg sync.WaitGroup

    ch := make(chan int)

    defer close(ch)

    go count(tree, true, ch, &wg)


    var total int

    wg.Add(1)

    go func(total *int) {

        for x := range ch {

            fmt.Println(x)

            *total += x

        }

        wg.Done()

    }(&total)

    wg.Wait()


    return total

}


func count(t *Tree, root bool, ch chan int, wg *sync.WaitGroup) {

    defer wg.Done()

    ch <- len(t.Leaves)

    if t.SubTrees != nil {

        wg.Add(len(t.SubTrees))

        for _, s := range t.SubTrees {

            go count(s, false, ch, wg)

        }

        wg.Wait()

    }


    if root {

        ch <- -1

    }

}

目前,我可以通过计算当前总数所需的通道收集所有数字,Leaves但函数永无止境。-1来自根Tree结构的终止值永远不会通过通道推送或接收,我也不知道为什么。


有任何想法吗?


潇潇雨雨
浏览 245回答 1
1回答
随时随地看视频慕课网APP

相关分类

Go
我要回答