152 lines
3.2 KiB
Go
152 lines
3.2 KiB
Go
package ds
|
|
|
|
// ds-btree.go
|
|
// 普通二叉树(不强制 BST 性质)+ 层序构造。
|
|
// 贴合 leetcode 题目里 [1,2,3,null,null,4,5] 这种层序数组表示。
|
|
// 复用 ds-tree.go 里定义的 TreeNode[T] 和 Ordered 约束,避免重复定义。
|
|
|
|
// BuildTree 从 leetcode 风格的层序数组构造二叉树。
|
|
// vals 中 *T 为 nil 的位置表示空节点;数组末尾的 nil 可省略。
|
|
// 示例:[1,2,3,nil,nil,4,5] →
|
|
//
|
|
// 1
|
|
// / \
|
|
// 2 3
|
|
// / \
|
|
// 4 5
|
|
func BuildTree[T Ordered](vals []*T) *TreeNode[T] {
|
|
if len(vals) == 0 || vals[0] == nil {
|
|
return nil
|
|
}
|
|
root := &TreeNode[T]{Val: *vals[0]}
|
|
q := &Queue[*TreeNode[T]]{}
|
|
q.Enqueue(root)
|
|
i := 1
|
|
for !q.Empty() && i < len(vals) {
|
|
node, _ := q.Dequeue()
|
|
// 左孩子
|
|
if i < len(vals) && vals[i] != nil {
|
|
node.Left = &TreeNode[T]{Val: *vals[i]}
|
|
q.Enqueue(node.Left)
|
|
}
|
|
i++
|
|
// 右孩子
|
|
if i < len(vals) && vals[i] != nil {
|
|
node.Right = &TreeNode[T]{Val: *vals[i]}
|
|
q.Enqueue(node.Right)
|
|
}
|
|
i++
|
|
}
|
|
return root
|
|
}
|
|
|
|
// TreeToLevelOrder 把树序列化回层序数组(与 BuildTree 互逆),nil 占位。
|
|
// 末尾连续的 nil 会被裁掉,与 leetcode 表示一致。
|
|
func TreeToLevelOrder[T any](root *TreeNode[T]) []*T {
|
|
if root == nil {
|
|
return nil
|
|
}
|
|
var out []*T
|
|
q := &Queue[*TreeNode[T]]{}
|
|
q.Enqueue(root)
|
|
for !q.Empty() {
|
|
node, _ := q.Dequeue()
|
|
if node == nil {
|
|
out = append(out, nil)
|
|
continue
|
|
}
|
|
v := node.Val
|
|
out = append(out, &v)
|
|
q.Enqueue(node.Left)
|
|
q.Enqueue(node.Right)
|
|
}
|
|
// 裁掉末尾 nil
|
|
for len(out) > 0 && out[len(out)-1] == nil {
|
|
out = out[:len(out)-1]
|
|
}
|
|
return out
|
|
}
|
|
|
|
// MaxDepth 求二叉树最大深度(空树 0,单节点 1)。对任意二叉树都适用,不限于 BST。
|
|
func MaxDepth[T any](root *TreeNode[T]) int {
|
|
if root == nil {
|
|
return 0
|
|
}
|
|
l := MaxDepth(root.Left)
|
|
r := MaxDepth(root.Right)
|
|
if l > r {
|
|
return l + 1
|
|
}
|
|
return r + 1
|
|
}
|
|
|
|
// InOrderAny 对任意二叉树做中序遍历(不限于 BST,结果未必有序)。
|
|
// 复用 TreeNode[T],不依赖 BST 类型,方便裸树题目直接调用。
|
|
func InOrderAny[T any](root *TreeNode[T]) []T {
|
|
var out []T
|
|
var walk func(*TreeNode[T])
|
|
walk = func(n *TreeNode[T]) {
|
|
if n == nil {
|
|
return
|
|
}
|
|
walk(n.Left)
|
|
out = append(out, n.Val)
|
|
walk(n.Right)
|
|
}
|
|
walk(root)
|
|
return out
|
|
}
|
|
|
|
// PreOrderAny 对任意二叉树做前序遍历。
|
|
func PreOrderAny[T any](root *TreeNode[T]) []T {
|
|
var out []T
|
|
var walk func(*TreeNode[T])
|
|
walk = func(n *TreeNode[T]) {
|
|
if n == nil {
|
|
return
|
|
}
|
|
out = append(out, n.Val)
|
|
walk(n.Left)
|
|
walk(n.Right)
|
|
}
|
|
walk(root)
|
|
return out
|
|
}
|
|
|
|
// PostOrderAny 对任意二叉树做后序遍历。
|
|
func PostOrderAny[T any](root *TreeNode[T]) []T {
|
|
var out []T
|
|
var walk func(*TreeNode[T])
|
|
walk = func(n *TreeNode[T]) {
|
|
if n == nil {
|
|
return
|
|
}
|
|
walk(n.Left)
|
|
walk(n.Right)
|
|
out = append(out, n.Val)
|
|
}
|
|
walk(root)
|
|
return out
|
|
}
|
|
|
|
// LevelOrderAny 对任意二叉树做层序遍历。裸树版,不依赖 BST。
|
|
func LevelOrderAny[T any](root *TreeNode[T]) []T {
|
|
if root == nil {
|
|
return nil
|
|
}
|
|
var out []T
|
|
q := &Queue[*TreeNode[T]]{}
|
|
q.Enqueue(root)
|
|
for !q.Empty() {
|
|
node, _ := q.Dequeue()
|
|
out = append(out, node.Val)
|
|
if node.Left != nil {
|
|
q.Enqueue(node.Left)
|
|
}
|
|
if node.Right != nil {
|
|
q.Enqueue(node.Right)
|
|
}
|
|
}
|
|
return out
|
|
}
|