/* 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/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 } 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) } 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 }