135 lines
3.2 KiB
Go
135 lines
3.2 KiB
Go
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
|
|
counter[current.Value.(*Node).ID].node = current.Value.(*Node)
|
|
// Прибавляем вес всем родительским нодам до корня
|
|
parentNode := counter[current.Value.(*Node).ID].parent
|
|
for {
|
|
if parentNode == nil {
|
|
break
|
|
}
|
|
currentNode := counter[parentNode.ID]
|
|
currentNode.weight = currentNode.weight + nodeWeight
|
|
parentNode = currentNode.parent
|
|
}
|
|
if len(current.Value.(*Node).Children) > 0 {
|
|
counter[current.Value.(*Node).ID].children = current.Value.(*Node).Children
|
|
}
|
|
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))
|
|
}
|