package main import ( "encoding/json" "maps" ) type Node struct { ID string `json:"id"` Name string `json:"name"` Children []*Node `json:"children"` } type WeightedNode struct { parent string weight uint16 } func (root Node) WeighingTreeWithRecursion() map[string]uint16 { weight := getNodeWeight(root.ID, root.Name) var res = make(map[string]uint16) for _, v := range root.Children { maps.Copy(res, v.WeighingTreeWithRecursion()) // Т.е. в go нет оптимизации хвостовой рекурсии, это породит неимоверное кол-во аллокаций. weight = weight + res[v.ID] } res[root.ID] = weight return res } func (root Node) WeighingTreeIdiomaticBFS() map[string]uint16 { weight := getNodeWeight(root.ID, root.Name) counter := map[string]*WeightedNode{root.ID: { weight: weight, }} stack := []*Node{&root} for len(stack) > 0 { current := stack[len(stack)-1] stack = stack[:len(stack)-1] nodeWeight := getNodeWeight(current.ID, current.Name) counter[current.ID].weight = nodeWeight // Прибавляем вес всем родительским нодам до корня parentID := counter[current.ID].parent for { currentNode := counter[parentID] if parentID == "" { break } currentNode.weight = currentNode.weight + nodeWeight parentID = currentNode.parent } for _, child := range current.Children { counter[child.ID] = &WeightedNode{ parent: current.ID, } stack = append(stack, child) } } var res = make(map[string]uint16) for k, v := range counter { res[k] = v.weight } return res } func (root Node) WeighingTreeIdiomaticDFS() map[string]uint16 { return nil } func (root Node) DecomposeTree(weights map[string]uint16, limit int) ([]*Node, error) { return nil, nil } func getNodeWeight(id string, name string) uint16 { nodeBytes, _ := json.Marshal(Node{ ID: id, Name: name, }) return uint16(len(nodeBytes)) }