You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
4.8 KiB

package solutions
type TreeNode struct {
Left, Right, Parent *TreeNode
Data string
}
func BTreeInsertData(bt *TreeNode, elem string) *TreeNode {
if bt == nil {
return &TreeNode{Data: elem}
}
if elem < bt.Data {
bt.Left = BTreeInsertData(bt.Left, elem)
bt.Left.Parent = bt
} else if elem >= bt.Data {
bt.Right = BTreeInsertData(bt.Right, elem)
bt.Right.Parent = bt
}
return bt
}
func BTreeApplyInorder(root *TreeNode, f func(...interface{}) (int, error)) {
if root != nil {
BTreeApplyInorder(root.Left, f)
f(root.Data)
BTreeApplyInorder(root.Right, f)
}
}
func BTreeApplyPreorder(root *TreeNode, f func(...interface{}) (int, error)) {
if root != nil {
f(root.Data)
BTreeApplyPreorder(root.Left, f)
BTreeApplyPreorder(root.Right, f)
}
}
func BTreeApplyPostorder(root *TreeNode, f func(...interface{}) (int, error)) {
if root != nil {
BTreeApplyPostorder(root.Left, f)
BTreeApplyPostorder(root.Right, f)
f(root.Data)
}
}
func BTreeSearchItem(root *TreeNode, elem string) *TreeNode {
if root == nil {
return nil
}
if root.Data == elem {
return root
}
if elem < root.Data {
return BTreeSearchItem(root.Left, elem)
}
return BTreeSearchItem(root.Right, elem)
}
func BTreeLevelCount(root *TreeNode) int {
if root == nil {
return 0
}
left := BTreeLevelCount(root.Left)
right := BTreeLevelCount(root.Right)
if left > right {
return left + 1
}
return right + 1
}
func BTreeIsBinary(root *TreeNode) bool {
condLeft := true
condRight := true
if root == nil {
return true
}
if root.Left != nil {
condLeft = BTreeIsBinary(root.Left) && root.Data >= root.Left.Data
}
if root.Right != nil {
condRight = BTreeIsBinary(root.Right) && root.Data <= root.Right.Data
}
return condLeft && condRight
}
func applyGivenOrder(root *TreeNode, level int, f func(...interface{}) (int, error)) {
if root == nil {
return
}
if level == 0 {
arg := interface{}(root.Data)
f(arg)
} else if level > 0 {
applyGivenOrder(root.Left, level-1, f)
applyGivenOrder(root.Right, level-1, f)
}
}
// Apply the function f level by level
func BTreeApplyByLevel(root *TreeNode, f func(...interface{}) (int, error)) {
h := BTreeLevelCount(root)
for i := 0; i < h; i++ {
applyGivenOrder(root, i, f)
}
}
/*-----------------------------------
* node-> (A) (B)
* / / \
* temp-> (B) --------> (C) (A)
* / \ /
* (C) [z] [z]
*------------------------------------*/
func BTreeRotateRight(node *TreeNode) *TreeNode {
if node == nil {
return nil
}
if node.Left == nil {
return node
}
temp := node.Left
node.Left = temp.Right
if temp.Right != nil {
temp.Right.Parent = node
}
if node.Parent != nil {
if node == node.Parent.Left {
node.Parent.Left = temp
} else {
node.Parent.Right = temp
}
}
temp.Right = node
temp.Parent = node.Parent
node.Parent = temp
return temp
}
/*------------------------------------
* node->(A) (B)
* \ / \
* temp-> (B) -------> (A) (C)
* / \ \
* [z] (C) [z]
*------------------------------------- */
func BTreeRotateLeft(node *TreeNode) *TreeNode {
if node == nil {
return nil
}
if node.Right == nil {
return node
}
temp := node.Right
node.Right = temp.Left
if temp.Left != nil {
temp.Left.Parent = node
}
if node.Parent != nil {
if node == node.Parent.Left {
node.Parent.Left = temp
} else {
node.Parent.Right = temp
}
}
temp.Left = node
temp.Parent = node.Parent
node.Parent = temp
return temp
}
// Returns the maximum node in the subtree started by root
func BTreeMax(root *TreeNode) *TreeNode {
if root == nil || root.Right == nil {
return root
}
return BTreeMax(root.Right)
}
// Returns the minimum value in the subtree started by root
func BTreeMin(root *TreeNode) *TreeNode {
if root == nil || root.Left == nil {
return root
}
return BTreeMin(root.Left)
}
func BTreeTransplant(root, node, repla *TreeNode) *TreeNode {
if root == nil {
return nil
}
replacement := node
if node.Parent == nil {
root = repla
} else if node == node.Parent.Left {
replacement.Parent.Left = repla
} else {
replacement.Parent.Right = repla
}
if repla != nil {
repla.Parent = node.Parent
}
return root
}
func BTreeDeleteNode(root, node *TreeNode) *TreeNode {
if node != nil {
if node.Left == nil {
root = BTreeTransplant(root, node, node.Right)
} else if node.Right == nil {
root = BTreeTransplant(root, node, node.Left)
} else {
y := BTreeMin(node.Right)
if y != nil && y.Parent != node {
root = BTreeTransplant(root, y, y.Right)
y.Right = node.Right
y.Right.Parent = y
}
root = BTreeTransplant(root, node, y)
y.Left = node.Left
y.Left.Parent = y
}
}
return root
}