Как создать идентичную копию дерева и сохранить ее на карте в Go

#go #pointers #tree

#Вперед #указатели #дерево

Вопрос:

У меня есть древовидная структура, где у любого узла может быть несколько дочерних элементов, но только один родительский. Узлы соединены указателями, и я хотел бы сохранить эту иерархию на карте, где я могу быстро получить доступ к дочерним и корневым узлам.

В настоящее время у меня есть версия, которая может выполнять желаемое поведение, но она сохраняет адреса входных данных на карте. Поэтому, если какой-либо из элементов на карте обновляется, он также обновляет исходную иерархию, чего я хотел бы избежать. Итак, я хотел бы сохранить точную копию моей иерархии на карте, которая имеет ту же структуру, но никак не связана с исходной. Что я делаю не так? Спасибо!

ссылка на игровую площадку

 type node struct {
value    string
children []*node
parent   *node
}

// isRoot returns true if node is a root
func (node *node) isRoot() bool {
    return node.parent == nil
}

var rootMap = make(map[string]*node)
var childrenMap = make(map[string]*node)

func main() {
    /*
          A
          |
          B
        /   
       C     D
    */

    a := node{value: "a"}
    b := node{value: "b", parent: amp;a}
    c := node{value: "c", parent: amp;b}
    d := node{value: "d", parent: amp;b}

    a.children = []*node{amp;b}
    b.children = []*node{amp;c, amp;d}

    storeHierarchy(amp;a)

    mappedA, _ := rootMap[a.value]
    mappedB, _ := childrenMap[b.value]

    fmt.Println(fmt.Sprintf("mappedA: %p, a: %p - not equal, which is perfect", mappedA, amp;a))
    fmt.Println(fmt.Sprintf("mappedB: %p, a: %p - not equal, which is perfect", mappedB, amp;b))

    fmt.Println(fmt.Sprintf("mappedA.child[0]: %p, a.child[0]: %p - these are equal, but should not be", mappedA.children[0], a.children[0]))
    fmt.Println(fmt.Sprintf("mappedA.child[0]: %p, first child b: %p - these are not equal, but should be", mappedA.children[0], mappedB))
}

func storeHierarchy(order *node) {
    orderCopy := *order
    order = amp;orderCopy

    for i := range order.children {
        child := order.children[i]
        storeHierarchy(child)
    }

    if order.isRoot() {
        rootMap[order.value] = order
    } else {
        childrenMap[order.value] = order
    }
}
 

Комментарии:

1. Ваш код создает копию узлов, которая включает в себя копирование children поля, которое является заголовком среза, дочерним элементам. Но вы никогда не меняете элементы children , поэтому они будут одинаковыми. Также обратите внимание, что для глубокой копии также потребуется клонировать фрагмент, поскольку назначение заголовка фрагмента будет указывать на тот же резервный массив. Кроме того, вы не изменяете parent поля скопированных узлов, поэтому они будут указывать на исходные узлы.

2. Спасибо за быстрый ответ. Позвольте мне попытаться исправить проблемы, о которых вы упомянули.