- debugging removal in red black tree (will carry on later)

pull/1/head
emirpasic 11 years ago
parent 5cd4ddeb6d
commit 1c6ebbbd32

@ -18,10 +18,12 @@ with this distribution for more information.
// Implementation of Red-black tree. // Implementation of Red-black tree.
// Used by TreeSet and TreeMap. // Used by TreeSet and TreeMap.
// Structure is not thread safe.
// References: http://en.wikipedia.org/wiki/Red%E2%80%93black_tree // References: http://en.wikipedia.org/wiki/Red%E2%80%93black_tree
package redblacktree package redblacktree
import ( import (
"fmt"
"github.com/emirpasic/gods/utils" "github.com/emirpasic/gods/utils"
) )
@ -121,18 +123,20 @@ func (tree *Tree) Remove(key interface{}) {
node.value = pred.value node.value = pred.value
node = pred node = pred
} }
if node.right == nil { if node.left == nil || node.right == nil {
child = node.left if node.right == nil {
} else { child = node.left
child = node.right } else {
} child = node.right
if node.color == BLACK { }
node.color = child.color if node.color == BLACK {
tree.deleteCase1(node) node.color = child.color
} tree.deleteCase1(node)
tree.replaceNode(node, child) }
if node.parent == nil && child != nil { tree.replaceNode(node, child)
child.color = BLACK if node.parent == nil && child != nil {
child.color = BLACK
}
} }
} }
@ -141,6 +145,39 @@ func (tree *Tree) IsEmpty() bool {
return tree.root == nil return tree.root == nil
} }
func (tree *Tree) String() string {
if !tree.IsEmpty() {
levels := make(map[int][]*Node)
lastLevel := 0
levels[lastLevel] = append(levels[lastLevel], tree.root)
for len(levels[lastLevel]) > 0 {
for _, node := range levels[lastLevel] {
if node.left != nil {
levels[lastLevel+1] = append(levels[lastLevel+1], node.left)
}
if node.right != nil {
levels[lastLevel+1] = append(levels[lastLevel+1], node.right)
}
}
lastLevel += 1
}
str := "tree\n"
for i := 0; i < lastLevel; i++ {
for _, node := range levels[i] {
str += fmt.Sprintf("%s", node)
}
str += "\n"
}
return str
}
return "tree\n"
}
func (node *Node) String() string {
return fmt.Sprintf("(%v)", node.key)
}
func (tree *Tree) lookup(key interface{}) *Node { func (tree *Tree) lookup(key interface{}) *Node {
node := tree.root node := tree.root
for node != nil { for node != nil {
@ -347,10 +384,10 @@ func (tree *Tree) deleteCase5(node *Node) {
func (tree *Tree) deleteCase6(node *Node) { func (tree *Tree) deleteCase6(node *Node) {
node.sibling().color = node.parent.color node.sibling().color = node.parent.color
node.parent.color = BLACK node.parent.color = BLACK
if node == node.parent.left { if node == node.parent.left && node.sibling().right.color == RED {
node.sibling().right.color = BLACK node.sibling().right.color = BLACK
tree.rotateLeft(node.parent) tree.rotateLeft(node.parent)
} else { } else if node.sibling().left.color == RED {
node.sibling().left.color = BLACK node.sibling().left.color = BLACK
tree.rotateRight(node.parent) tree.rotateRight(node.parent)
} }

@ -2,13 +2,17 @@ package redblacktree
import ( import (
"testing" "testing"
"log"
) )
func TestPutGet(t *testing.T) { func TestRedBlackTree(t *testing.T) {
tree := NewWithIntComparator() tree := NewWithIntComparator()
// insertions
tree.Put(5, "e") tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c") tree.Put(3, "c")
tree.Put(4, "d") tree.Put(4, "d")
tree.Put(1, "x") tree.Put(1, "x")
@ -16,18 +20,51 @@ func TestPutGet(t *testing.T) {
tree.Put(1, "a") //overwrite tree.Put(1, "a") //overwrite
// key,expectedValue,expectedFound // key,expectedValue,expectedFound
tests := [][]interface{}{ tests1 := [][]interface{}{
{1, "a", true},
{2, "b", true},
{3, "c", true},
{4, "d", true},
{5, "e", true},
{6, "f", true},
{7, "g", true},
{8, nil, false},
}
for _, test := range tests1 {
// retrievals
actualValue, actualFound := tree.Get(test[0])
if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1])
}
}
// removals
log.Println(tree)
tree.Remove(5)
log.Println(tree)
tree.Remove(6)
tree.Remove(7)
tree.Remove(8)
tests2 := [][]interface{}{
{1, "a", true}, {1, "a", true},
{2, "b", true}, {2, "b", true},
{3, "c", true}, {3, "c", true},
{4, "d", true}, {4, "d", true},
{5, nil, false}, {5, nil, false},
{6, nil, false},
{7, nil, false},
{8, nil, false},
} }
for _, test := range tests { for _, test := range tests2 {
// retrievals
actualValue, actualFound := tree.Get(test[0]) actualValue, actualFound := tree.Get(test[0])
if actualValue != test[1] || actualFound != test[2] { if actualValue != test[1] || actualFound != test[2] {
t.Errorf("Got %v expected %v", actualValue, test[1]) t.Errorf("Got %v expected %v", actualValue, test[1])
} }
} }
} }

Loading…
Cancel
Save