Intro

层次遍历的时候返现每次执行次数都不同,溯源发现问题出现在这一行代码:

for _, node := range currentNode.subCategory {
queue = append(queue, append(currentPath, node))
}

queue 的结果会影响遍历的内容以及结束条件

append

append 是给 slice(切片) 追加内容的方法

// 添加单个
append(a, b)
// 添加多个
append(a, b, c)
append(a, [b,c]...)

slice 是在数组基础上生成的,有三个属性

[]Type:切片内容

length:切片内容的长度

capacity: 切片容量

capacity 表示当前分配给这个 slice 的内存大小,在 make slice 的时候可以指定它( 如果不指定 capacity 也会随着需要自动增长)

slice := make([]Type, 0, 0)
// 一定有
cap(slce) >= len(slice)

b被添加时,如果 a 的 capacity 不够了会返回一个 capacity 更大的新 slice。

如果每次 append capacity 都增长一次返回新的 slice 那这就是我希望加入到 queue 里的结果,但是 go 在 slice 被 append 的时候会智能的分配内存大小,而是当 capacity 不够时会增长为原来的两倍

因此在前三次 append 时,currentPath 的 capacity 从 1 变到 2 再到 4, append(currentPath, node)都会把新的 slice 加入 queue 中;

第三次添加时 capacity * 2 变成了 4, 于是在第四次 append 的时候不会生成新的 currentPath ,相当于执行了

currentPath[3] = node

这时候加到 queue 中的就不是新的 slice,而是原来的公用的 currentPath,最终加入到queue 的所有 currentPath 的第 4 个值由最后一次 append 决定,所以产生了重复的 node。

解决办法:手动创建新的 slice

for _, node := range currentNode.subCategory {
// 顺便设置了下已知的长度
subPath := make(PddCategoryNodePath, len(currentPath)+1)
// 复制创建新 slice
copy(subPath, currentPath)
subPath[len(subPath)-1] = node
queue = append(queue, subPath)
}