tests/cut_the_tree/funcs.go
Андрей Иванов c6d33c500d
All checks were successful
continuous-integration/drone/push Build is passing
Закончил бенчмарки
2024-09-13 13:11:29 +03:00

123 lines
2.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"encoding/json"
"maps"
"tests/cut_the_tree/dll"
)
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) WeightingTreeWithRecursion() map[string]uint16 {
weight := root.getNodeWeight()
var res = make(map[string]uint16)
for _, v := range root.Children {
maps.Copy(res, v.WeightingTreeWithRecursion()) // Т.е. в go нет оптимизации хвостовой рекурсии, это породит неимоверное кол-во аллокаций.
weight = weight + res[v.ID]
}
res[root.ID] = weight
return res
}
func (root Node) WeightingTreeWithStack() map[string]uint16 {
weight := root.getNodeWeight()
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 := current.getNodeWeight()
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) WeightingTreeWithDLL() map[string]uint16 {
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
// Прибавляем вес всем родительским нодам до корня
parentID := counter[current.Value.(Node).ID].parent
for {
currentNode := counter[parentID]
if parentID == "" {
break
}
currentNode.weight = currentNode.weight + nodeWeight
parentID = currentNode.parent
}
for _, child := range current.Value.(Node).Children {
counter[child.ID] = &WeightedNode{
parent: current.Value.(Node).ID,
}
dllist.PushFront(*child)
}
}
var res = make(map[string]uint16)
for k, v := range counter {
res[k] = v.weight
}
return res
}
func (root Node) DecomposeTree(weights map[string]uint16, limit int) ([]*Node, error) {
return nil, nil
}
func (n Node) getNodeWeight() uint16 {
nodeBytes, _ := json.Marshal(Node{
ID: n.ID,
Name: n.Name,
})
return uint16(len(nodeBytes))
}