mirror of
https://github.com/duke-git/lancet.git
synced 2026-03-01 00:35:28 +08:00
feat: add IsSubTree func for BSTree
This commit is contained in:
@@ -40,12 +40,12 @@ func NewQueueNode[T any](value T) *QueueNode[T] {
|
|||||||
|
|
||||||
// TreeNode is node of tree
|
// TreeNode is node of tree
|
||||||
type TreeNode[T any] struct {
|
type TreeNode[T any] struct {
|
||||||
Data T
|
Value T
|
||||||
Left *TreeNode[T]
|
Left *TreeNode[T]
|
||||||
Right *TreeNode[T]
|
Right *TreeNode[T]
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTreeNode return a TreeNode pointer
|
// NewTreeNode return a TreeNode pointer
|
||||||
func NewTreeNode[T any](data T) *TreeNode[T] {
|
func NewTreeNode[T any](val T) *TreeNode[T] {
|
||||||
return &TreeNode[T]{data, nil, nil}
|
return &TreeNode[T]{val, nil, nil}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,31 @@ func (t *BSTree[T]) Depth() int {
|
|||||||
return calculateDepth(t.root, 0)
|
return calculateDepth(t.root, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsSubTree checks if the tree `t`` has `subTree` or not
|
||||||
|
func (t *BSTree[T]) IsSubTree(subTree *BSTree[T]) bool {
|
||||||
|
return isSubTree(t.root, subTree.root, t.comparator)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSubTree[T any](superTreeRoot, subTreeRoot *datastructure.TreeNode[T],
|
||||||
|
comparator lancetconstraints.Comparator) bool {
|
||||||
|
res := false
|
||||||
|
|
||||||
|
if superTreeRoot != nil && subTreeRoot != nil {
|
||||||
|
if comparator.Compare(superTreeRoot.Value, subTreeRoot.Value) == 0 {
|
||||||
|
res = hasSubTree(superTreeRoot, subTreeRoot, comparator)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !res {
|
||||||
|
res = isSubTree(superTreeRoot.Left, subTreeRoot, comparator)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !res {
|
||||||
|
res = isSubTree(superTreeRoot.Right, subTreeRoot, comparator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
// Print the bstree structure
|
// Print the bstree structure
|
||||||
func (t *BSTree[T]) Print() {
|
func (t *BSTree[T]) Print() {
|
||||||
maxLevel := t.NodeLevel(t.root)
|
maxLevel := t.NodeLevel(t.root)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
func preOrderTraverse[T any](node *datastructure.TreeNode[T]) []T {
|
func preOrderTraverse[T any](node *datastructure.TreeNode[T]) []T {
|
||||||
data := []T{}
|
data := []T{}
|
||||||
if node != nil {
|
if node != nil {
|
||||||
data = append(data, node.Data)
|
data = append(data, node.Value)
|
||||||
data = append(data, preOrderTraverse(node.Left)...)
|
data = append(data, preOrderTraverse(node.Left)...)
|
||||||
data = append(data, preOrderTraverse(node.Right)...)
|
data = append(data, preOrderTraverse(node.Right)...)
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ func postOrderTraverse[T any](node *datastructure.TreeNode[T]) []T {
|
|||||||
if node != nil {
|
if node != nil {
|
||||||
data = append(data, preOrderTraverse(node.Left)...)
|
data = append(data, preOrderTraverse(node.Left)...)
|
||||||
data = append(data, preOrderTraverse(node.Right)...)
|
data = append(data, preOrderTraverse(node.Right)...)
|
||||||
data = append(data, node.Data)
|
data = append(data, node.Value)
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ func inOrderTraverse[T any](node *datastructure.TreeNode[T]) []T {
|
|||||||
data := []T{}
|
data := []T{}
|
||||||
if node != nil {
|
if node != nil {
|
||||||
data = append(data, inOrderTraverse(node.Left)...)
|
data = append(data, inOrderTraverse(node.Left)...)
|
||||||
data = append(data, node.Data)
|
data = append(data, node.Value)
|
||||||
data = append(data, inOrderTraverse(node.Right)...)
|
data = append(data, inOrderTraverse(node.Right)...)
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
@@ -43,7 +43,7 @@ func preOrderPrint[T any](node *datastructure.TreeNode[T]) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("%v, ", node.Data)
|
fmt.Printf("%v, ", node.Value)
|
||||||
preOrderPrint(node.Left)
|
preOrderPrint(node.Left)
|
||||||
preOrderPrint(node.Right)
|
preOrderPrint(node.Right)
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ func postOrderPrint[T any](node *datastructure.TreeNode[T]) {
|
|||||||
|
|
||||||
preOrderPrint(node.Left)
|
preOrderPrint(node.Left)
|
||||||
preOrderPrint(node.Right)
|
preOrderPrint(node.Right)
|
||||||
fmt.Printf("%v, ", node.Data)
|
fmt.Printf("%v, ", node.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func inOrderPrint[T any](node *datastructure.TreeNode[T]) {
|
func inOrderPrint[T any](node *datastructure.TreeNode[T]) {
|
||||||
@@ -64,7 +64,7 @@ func inOrderPrint[T any](node *datastructure.TreeNode[T]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inOrderPrint(node.Left)
|
inOrderPrint(node.Left)
|
||||||
fmt.Printf("%v, ", node.Data)
|
fmt.Printf("%v, ", node.Value)
|
||||||
inOrderPrint(node.Right)
|
inOrderPrint(node.Right)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ func levelOrderTraverse[T any](root *datastructure.TreeNode[T], traversal *[]T)
|
|||||||
|
|
||||||
for len(q) != 0 {
|
for len(q) != 0 {
|
||||||
n, q = q[0], q[1:]
|
n, q = q[0], q[1:]
|
||||||
*traversal = append(*traversal, n.Data)
|
*traversal = append(*traversal, n.Value)
|
||||||
if n.Left != nil {
|
if n.Left != nil {
|
||||||
q = append(q, n.Left)
|
q = append(q, n.Left)
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ func levelOrderTraverse[T any](root *datastructure.TreeNode[T], traversal *[]T)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func insertTreeNode[T any](rootNode, newNode *datastructure.TreeNode[T], comparator lancetconstraints.Comparator) {
|
func insertTreeNode[T any](rootNode, newNode *datastructure.TreeNode[T], comparator lancetconstraints.Comparator) {
|
||||||
if comparator.Compare(newNode.Data, rootNode.Data) == -1 {
|
if comparator.Compare(newNode.Value, rootNode.Value) == -1 {
|
||||||
if rootNode.Left == nil {
|
if rootNode.Left == nil {
|
||||||
rootNode.Left = newNode
|
rootNode.Left = newNode
|
||||||
} else {
|
} else {
|
||||||
@@ -107,9 +107,9 @@ func deleteTreeNode[T any](node *datastructure.TreeNode[T], data T, comparator l
|
|||||||
if node == nil {
|
if node == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if comparator.Compare(data, node.Data) == -1 {
|
if comparator.Compare(data, node.Value) == -1 {
|
||||||
node.Left = deleteTreeNode(node.Left, data, comparator)
|
node.Left = deleteTreeNode(node.Left, data, comparator)
|
||||||
} else if comparator.Compare(data, node.Data) == 1 {
|
} else if comparator.Compare(data, node.Value) == 1 {
|
||||||
node.Right = deleteTreeNode(node.Right, data, comparator)
|
node.Right = deleteTreeNode(node.Right, data, comparator)
|
||||||
} else {
|
} else {
|
||||||
if node.Left == nil {
|
if node.Left == nil {
|
||||||
@@ -150,7 +150,7 @@ func printTreeNodes[T any](nodes []*datastructure.TreeNode[T], level, maxLevel i
|
|||||||
newNodes := []*datastructure.TreeNode[T]{}
|
newNodes := []*datastructure.TreeNode[T]{}
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
if node != nil {
|
if node != nil {
|
||||||
fmt.Printf("%v", node.Data)
|
fmt.Printf("%v", node.Value)
|
||||||
newNodes = append(newNodes, node.Left)
|
newNodes = append(newNodes, node.Left)
|
||||||
newNodes = append(newNodes, node.Right)
|
newNodes = append(newNodes, node.Right)
|
||||||
} else {
|
} else {
|
||||||
@@ -216,6 +216,20 @@ func calculateDepth[T any](node *datastructure.TreeNode[T], depth int) int {
|
|||||||
return max(calculateDepth(node.Left, depth+1), calculateDepth(node.Right, depth+1))
|
return max(calculateDepth(node.Left, depth+1), calculateDepth(node.Right, depth+1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hasSubTree[T any](superTreeRoot, subTreeRoot *datastructure.TreeNode[T], comparator lancetconstraints.Comparator) bool {
|
||||||
|
if subTreeRoot == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if superTreeRoot == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if comparator.Compare(superTreeRoot.Value, subTreeRoot.Value) != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasSubTree(superTreeRoot.Left, subTreeRoot.Left, comparator) && hasSubTree(superTreeRoot.Right, subTreeRoot.Right, comparator)
|
||||||
|
}
|
||||||
|
|
||||||
func max(a, b int) int {
|
func max(a, b int) int {
|
||||||
if a > b {
|
if a > b {
|
||||||
return a
|
return a
|
||||||
|
|||||||
Reference in New Issue
Block a user