package main import ( "encoding/json" "maps" "tests/weghting_the_tree/dll" ) type Node struct { ID string `json:"id"` Name string `json:"name"` Children []*Node `json:"children"` } type WeightedNode struct { node *Node parent *Node children []*Node weight uint16 } func (root *Node) WeightingTreeWithRecursion(parent *Node) map[string]*WeightedNode { weightedNode := &Node{ ID: root.ID, Name: root.Name, Children: []*Node{}, } weight := weightedNode.getNodeWeight() var res = map[string]*WeightedNode{ root.ID: { node: root, parent: parent, weight: weight, }, } for _, v := range root.Children { maps.Copy(res, v.WeightingTreeWithRecursion(root)) weight = weight + res[v.ID].weight res[root.ID].children = append(res[root.ID].children, v) } res[root.ID].weight = weight return res } func (root *Node) WeightingTreeWithStack(parent *Node) map[string]*WeightedNode { weight := root.getNodeWeight() res := 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 := current.getNodeWeight() res[current.ID].weight = nodeWeight // Прибавляем вес всем родительским нодам до корня parentNode := res[current.ID].parent for { if parentNode == nil { break } currentNode := res[parentNode.ID] currentNode.weight = currentNode.weight + nodeWeight parentNode = currentNode.parent } res[current.ID].node = current if len(current.Children) > 0 { res[current.ID].children = current.Children } for _, child := range current.Children { res[child.ID] = &WeightedNode{ parent: current, } stack = append(stack, child) } } return res } func (root *Node) WeightingTreeWithDLL(parent *Node) map[string]*WeightedNode { weight := root.getNodeWeight() counter := map[string]*WeightedNode{root.ID: { weight: weight, }} dllist := dll.NewList() dllist.PushFront(*root) for dllist.Len() > 0 { current := dllist.Front() dllist.Remove(current) nodeWeight := current.Value.(*Node).getNodeWeight() counter[current.Value.(*Node).ID].weight = nodeWeight // Прибавляем вес всем родительским нодам до корня parentNode := counter[current.Value.(*Node).ID].parent for { if parentNode == nil { break } currentNode := counter[parentNode.ID] currentNode.weight = currentNode.weight + nodeWeight parentNode = currentNode.parent } for _, child := range current.Value.(*Node).Children { counter[child.ID] = &WeightedNode{ parent: current.Value.(*Node), } dllist.PushFront(*child) } } return counter } //func DecomposeTree(tree map[string]*WeightedNode, limit int) ([]SubTree, error) { // // return nil, nil //} func (n *Node) getNodeWeight() uint16 { weighted := &Node{ ID: n.ID, Name: n.Name, Children: []*Node{}, } nodeBytes, _ := json.Marshal(weighted) return uint16(len(nodeBytes)) }