当然可以。如果您的所有节点都保存在数据库中,并且您使用节点的ID来表示子节点,那么您可以将Children []*Node改为Children []int,用来存储子节点的ID。
以下是修改后的代码示例:
package main
import (
"fmt"
)
type Node struct {
ID int
Name string
ParentID int
Children []int // 存储子节点的ID
}
func main() {
nodes := make(map[int]*Node) // 模拟从数据库获取到的所有节点数据
root := &Node{1, "Root", 0, nil}
nodes[root.ID] = root
insertNode(nodes, 2, "Child 1", 1) // 合法插入 Child 1 到根节点下
insertNode(nodes, 3, "Grandchild 1", 2) // 合法插入 Grandchild 1 到 Child 1 下
insertNode(nodes, 4, "Invalid Node", 5) // 非法插入,父节点不存在
fmt.Println("Before deletion:")
printTree(nodes, root.ID, "")
deleteNode(nodes, root.Children[0]) // 删除第一个子节点及其所有后代节点
fmt.Println("\nAfter deletion:")
printTree(nodes, root.ID, "")
}
// 树节点插入函数,判断父节点是否存在以及插入后是否会破坏树结构的合法性
func insertNode(nodes map[int]*Node, id int, name string, parentID int) bool {
parent := nodes[parentID]
if parent == nil {
return false // 父节点不存在,插入失败
}
node := &Node{id, name, parentID, nil}
nodes[id] = node
parent.Children = append(parent.Children, id)
return true // 插入成功
}
// 删除指定节点及其所有子节点(递归方式)
func deleteNode(nodes map[int]*Node, id int) {
node := nodes[id]
if node == nil {
return
}
for _, childID := range node.Children {
deleteNode(nodes, childID)
delete(nodes, childID) // 从节点映射表中删除子节点
}
parent := nodes[node.ParentID]
if parent != nil {
for i, childID := range parent.Children {
if childID == id {
parent.Children = append(parent.Children[:i], parent.Children[i+1:]...)
break
}
}
}
delete(nodes, id) // 从节点映射表中删除当前节点
}
// 递归打印树形结构
func printTree(nodes map[int]*Node, id int, indent string) {
node := nodes[id]
fmt.Println(indent + node.Name)
for _, childID := range node.Children {
printTree(nodes, childID, indent+" ")
}
}
请注意,上述示例代码使用了一个名为nodes的映射来模拟从数据库获取到的所有节点数据,并且在插入和删除操作时进行相应的更新。这样,您可以根据实际情况将该部分代码替换为与数据库交互的逻辑。
内容由零声教学AI助手提供,问题来源于学员提问




