|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Refactor & Beautify & destruction commit
return early, remove else branches, reorder conditions and top-level functions, remove empty lines, remove unnecessary append(), fix typos, stop using testing package, remove dead code, fix mistakes in subjects, tests and solutions, remove disclaimers, reformat comments, simplify solutions, tests, add more instructions to subjects, remove obsolete files, etc.
Some of the reasons behind those modifications will be added to good-practices.en.md
Some of the exercises are now broken, they will have to be fixed, most of them have a "TODO:" comment.
5 years ago
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
Refactor & Beautify & destruction commit
return early, remove else branches, reorder conditions and top-level functions, remove empty lines, remove unnecessary append(), fix typos, stop using testing package, remove dead code, fix mistakes in subjects, tests and solutions, remove disclaimers, reformat comments, simplify solutions, tests, add more instructions to subjects, remove obsolete files, etc.
Some of the reasons behind those modifications will be added to good-practices.en.md
Some of the exercises are now broken, they will have to be fixed, most of them have a "TODO:" comment.
5 years ago
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
|
Refactor & Beautify & destruction commit
return early, remove else branches, reorder conditions and top-level functions, remove empty lines, remove unnecessary append(), fix typos, stop using testing package, remove dead code, fix mistakes in subjects, tests and solutions, remove disclaimers, reformat comments, simplify solutions, tests, add more instructions to subjects, remove obsolete files, etc.
Some of the reasons behind those modifications will be added to good-practices.en.md
Some of the exercises are now broken, they will have to be fixed, most of them have a "TODO:" comment.
5 years ago
|
|
|
// 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
|
|
|
|
}
|