gods/trees/redblacktree/redblacktree.go
2015-03-05 15:05:12 +01:00

475 lines
10 KiB
Go

/*
Copyright (c) Emir Pasic, All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. See the file LICENSE included
with this distribution for more information.
*/
// Implementation of Red-black tree.
// Used by TreeSet and TreeMap.
// Structure is not thread safe.
// References: http://en.wikipedia.org/wiki/Red%E2%80%93black_tree
package redblacktree
import (
"fmt"
"github.com/emirpasic/gods/stacks/linkedliststack"
"github.com/emirpasic/gods/utils"
)
type color bool
const (
black, red color = true, false
)
type Tree struct {
root *node
size int
comparator utils.Comparator
}
type node struct {
key interface{}
value interface{}
color color
left *node
right *node
parent *node
}
// Instantiates a red-black tree with the custom comparator.
func NewWith(comparator utils.Comparator) *Tree {
return &Tree{comparator: comparator}
}
// Instantiates a red-black tree with the IntComparator, i.e. keys are of type int.
func NewWithIntComparator() *Tree {
return &Tree{comparator: utils.IntComparator}
}
// Instantiates a red-black tree with the StringComparator, i.e. keys are of type string.
func NewWithStringComparator() *Tree {
return &Tree{comparator: utils.StringComparator}
}
// Inserts node into the tree.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Put(key interface{}, value interface{}) {
insertedNode := &node{key: key, value: value, color: red}
if tree.root == nil {
tree.root = insertedNode
} else {
node := tree.root
loop := true
for loop {
compare := tree.comparator(key, node.key)
switch {
case compare == 0:
node.value = value
return
case compare < 0:
if node.left == nil {
node.left = insertedNode
loop = false
} else {
node = node.left
}
case compare > 0:
if node.right == nil {
node.right = insertedNode
loop = false
} else {
node = node.right
}
}
}
insertedNode.parent = node
}
tree.insertCase1(insertedNode)
tree.size += 1
}
// Searches the node in the tree by key and returns its value or nil if key is not found in tree.
// Second return parameter is true if key was found, otherwise false.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Get(key interface{}) (value interface{}, found bool) {
node := tree.lookup(key)
if node != nil {
return node.value, true
}
return nil, false
}
// Remove the node from the tree by key.
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Remove(key interface{}) {
var child *node
node := tree.lookup(key)
if node == nil {
return
}
if node.left != nil && node.right != nil {
pred := node.left.maximumNode()
node.key = pred.key
node.value = pred.value
node = pred
}
if node.left == nil || node.right == nil {
if node.right == nil {
child = node.left
} else {
child = node.right
}
if node.color == black {
node.color = nodeColor(child)
tree.deleteCase1(node)
}
tree.replaceNode(node, child)
if node.parent == nil && child != nil {
child.color = black
}
}
tree.size -= 1
}
// Returns true if tree does not contain any nodes
func (tree *Tree) Empty() bool {
return tree.size == 0
}
// Returns number of nodes in the tree.
func (tree *Tree) Size() int {
return tree.size
}
// Returns all keys in-order
func (tree *Tree) Keys() []interface{} {
keys := make([]interface{}, tree.size)
for i, node := range tree.inOrder() {
keys[i] = node.key
}
return keys
}
// Returns all values in-order based on the key.
func (tree *Tree) Values() []interface{} {
values := make([]interface{}, tree.size)
for i, node := range tree.inOrder() {
values[i] = node.value
}
return values
}
// Removes all nodes from the tree.
func (tree *Tree) Clear() {
tree.root = nil
tree.size = 0
}
func (tree *Tree) String() string {
str := "RedBlackTree\n"
if !tree.Empty() {
output(tree.root, "", true, &str)
}
return str
}
func (node *node) String() string {
return fmt.Sprintf("%v", node.key)
}
// Returns all nodes in order
func (tree *Tree) inOrder() []*node {
nodes := make([]*node, tree.size)
if tree.size > 0 {
current := tree.root
stack := linkedliststack.New()
done := false
count := 0
for !done {
if current != nil {
stack.Push(current)
current = current.left
} else {
if !stack.Empty() {
currentPop, _ := stack.Pop()
current = currentPop.(*node)
nodes[count] = current
count += 1
current = current.right
} else {
done = true
}
}
}
}
return nodes
}
func output(node *node, prefix string, isTail bool, str *string) {
if node.right != nil {
newPrefix := prefix
if isTail {
newPrefix += "│ "
} else {
newPrefix += " "
}
output(node.right, newPrefix, false, str)
}
*str += prefix
if isTail {
*str += "└── "
} else {
*str += "┌── "
}
*str += node.String() + "\n"
if node.left != nil {
newPrefix := prefix
if isTail {
newPrefix += " "
} else {
newPrefix += "│ "
}
output(node.left, newPrefix, true, str)
}
}
func (tree *Tree) lookup(key interface{}) *node {
node := tree.root
for node != nil {
compare := tree.comparator(key, node.key)
switch {
case compare == 0:
return node
case compare < 0:
node = node.left
case compare > 0:
node = node.right
}
}
return nil
}
func (node *node) grandparent() *node {
if node != nil && node.parent != nil {
return node.parent.parent
}
return nil
}
func (node *node) uncle() *node {
if node == nil || node.parent == nil || node.parent.parent == nil {
return nil
}
return node.parent.sibling()
}
func (node *node) sibling() *node {
if node == nil || node.parent == nil {
return nil
}
if node == node.parent.left {
return node.parent.right
} else {
return node.parent.left
}
}
func (tree *Tree) rotateLeft(node *node) {
right := node.right
tree.replaceNode(node, right)
node.right = right.left
if right.left != nil {
right.left.parent = node
}
right.left = node
node.parent = right
}
func (tree *Tree) rotateRight(node *node) {
left := node.left
tree.replaceNode(node, left)
node.left = left.right
if left.right != nil {
left.right.parent = node
}
left.right = node
node.parent = left
}
func (tree *Tree) replaceNode(old *node, new *node) {
if old.parent == nil {
tree.root = new
} else {
if old == old.parent.left {
old.parent.left = new
} else {
old.parent.right = new
}
}
if new != nil {
new.parent = old.parent
}
}
func (tree *Tree) insertCase1(node *node) {
if node.parent == nil {
node.color = black
} else {
tree.insertCase2(node)
}
}
func (tree *Tree) insertCase2(node *node) {
if nodeColor(node.parent) == black {
return
}
tree.insertCase3(node)
}
func (tree *Tree) insertCase3(node *node) {
uncle := node.uncle()
if nodeColor(uncle) == red {
node.parent.color = black
uncle.color = black
node.grandparent().color = red
tree.insertCase1(node.grandparent())
} else {
tree.insertCase4(node)
}
}
func (tree *Tree) insertCase4(node *node) {
grandparent := node.grandparent()
if node == node.parent.right && node.parent == grandparent.left {
tree.rotateLeft(node.parent)
node = node.left
} else if node == node.parent.left && node.parent == grandparent.right {
tree.rotateRight(node.parent)
node = node.right
}
tree.insertCase5(node)
}
func (tree *Tree) insertCase5(node *node) {
node.parent.color = black
grandparent := node.grandparent()
grandparent.color = red
if node == node.parent.left && node.parent == grandparent.left {
tree.rotateRight(grandparent)
} else if node == node.parent.right && node.parent == grandparent.right {
tree.rotateLeft(grandparent)
}
}
func (node *node) maximumNode() *node {
if node == nil {
return nil
}
for node.right != nil {
node = node.right
}
return node
}
func (tree *Tree) deleteCase1(node *node) {
if node.parent == nil {
return
} else {
tree.deleteCase2(node)
}
}
func (tree *Tree) deleteCase2(node *node) {
sibling := node.sibling()
if nodeColor(sibling) == red {
node.parent.color = red
sibling.color = black
if node == node.parent.left {
tree.rotateLeft(node.parent)
} else {
tree.rotateRight(node.parent)
}
}
tree.deleteCase3(node)
}
func (tree *Tree) deleteCase3(node *node) {
sibling := node.sibling()
if nodeColor(node.parent) == black &&
nodeColor(sibling) == black &&
nodeColor(sibling.left) == black &&
nodeColor(sibling.right) == black {
sibling.color = red
tree.deleteCase1(node.parent)
} else {
tree.deleteCase4(node)
}
}
func (tree *Tree) deleteCase4(node *node) {
sibling := node.sibling()
if nodeColor(node.parent) == red &&
nodeColor(sibling) == black &&
nodeColor(sibling.left) == black &&
nodeColor(sibling.right) == black {
sibling.color = red
node.parent.color = black
} else {
tree.deleteCase5(node)
}
}
func (tree *Tree) deleteCase5(node *node) {
sibling := node.sibling()
if node == node.parent.left &&
nodeColor(sibling) == black &&
nodeColor(sibling.left) == red &&
nodeColor(sibling.right) == black {
sibling.color = red
sibling.left.color = black
tree.rotateRight(sibling)
} else if node == node.parent.right &&
nodeColor(sibling) == black &&
nodeColor(sibling.right) == red &&
nodeColor(sibling.left) == black {
sibling.color = red
sibling.right.color = black
tree.rotateLeft(sibling)
}
tree.deleteCase6(node)
}
func (tree *Tree) deleteCase6(node *node) {
sibling := node.sibling()
sibling.color = nodeColor(node.parent)
node.parent.color = black
if node == node.parent.left && nodeColor(sibling.right) == red {
sibling.right.color = black
tree.rotateLeft(node.parent)
} else if nodeColor(sibling.left) == red {
sibling.left.color = black
tree.rotateRight(node.parent)
}
}
func nodeColor(node *node) color {
if node == nil {
return black
}
return node.color
}