Skip to content
This repository has been archived by the owner on Feb 18, 2018. It is now read-only.

Commit

Permalink
Fixed bug in removal
Browse files Browse the repository at this point in the history
  • Loading branch information
mads-hartmann committed May 13, 2011
1 parent 8f575e6 commit 01d93e5
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 20 deletions.
38 changes: 31 additions & 7 deletions src/RedBlackTree.coffee
Expand Up @@ -53,7 +53,7 @@ mugs.RedBlackLeaf = (color) ->
this

mugs.RedBlackLeaf.prototype.copy = (properties) ->
new mugs.RedBlackLeaf(properties.color | this.color)
new mugs.RedBlackLeaf(properties.color || this.color)

mugs.RedBlackLeaf.prototype.isEmpty = () -> true
mugs.RedBlackLeaf.prototype.containsKey = (key) -> false
Expand Down Expand Up @@ -171,7 +171,6 @@ mugs.RedBlackNode.prototype.values = () ->
###
mugs.RedBlackNode.prototype.inorderTraversal = (f) ->
if !this.left.isEmpty() then this.left.inorderTraversal(f)
console.log("inorder on: " + this.value)
f({key: this.key, value: this.value})
if !this.right.isEmpty() then this.right.inorderTraversal(f)

Expand Down Expand Up @@ -205,10 +204,8 @@ mugs.RedBlackNode.prototype.remove = (key) ->
__rm = (tree) =>
isExternalNode = () -> tree.left.isEmpty() && tree.right.isEmpty()
isInternalNode = () -> !tree.left.isEmpty() && !tree.right.isEmpty()
isNodeWithOneChildLeft = () -> (tree.color == mugs.RedBlack.BLACK) &&
(tree.left.color == mugs.RedBlack.RED && tree.right.isEmpty() )
isNodeWithOneChildRight = () -> (tree.color == mugs.RedBlack.BLACK) &&
(tree.right.color == mugs.RedBlack.RED && tree.left.isEmpty())
isNodeWithOneChildLeft = () -> tree.right.isEmpty()
isNodeWithOneChildRight = () -> tree.left.isEmpty()
# The __rm call traversed all the way to the bottom of the tree. This happens
# when the item to remove wasn't in the tree.
if ( tree.isEmpty() )
Expand Down Expand Up @@ -377,7 +374,7 @@ mugs.RedBlackNode.prototype.balance = (color, left, key, value, right) ->
right.left.key,
right.left.value,
#x
new mugs.RedBlackNode(mugs.RedBlack.Black,
new mugs.RedBlackNode(mugs.RedBlack.BLACK,
right.left.right, #3
right.key,
right.value,
Expand All @@ -397,3 +394,30 @@ mugs.RedBlackNode.prototype.balance = (color, left, key, value, right) ->
A node is never empty
###
mugs.RedBlackNode.prototype.isEmpty = () -> false

###
RELATED TO TESTING
###

mugs.RedBlackLeaf.prototype.count_ = () -> 0
mugs.RedBlackLeaf.prototype.check_ = () ->
return 1 if this.color == mugs.RedBlack.BLACK
return 2 if this.color == mugs.RedBlack.DOUBLE_BLACK

mugs.RedBlackNode.prototype.count_ = () ->
this.left.count_() + 1 + this.right.count_()

# returns the black-depth if three is well-formed, else throws an exception
mugs.RedBlackNode.prototype.check_ = () ->
if this.color == RED && this.left.color == RED
throw new Error("Red node has red child(" + node.key+","+node.value+")")
blackDepth = this.left.check_()
if blackDepth != this.right.check_()
throw new Error("Black depths differ")
else
return blackDepth + 1 if this.color == mugs.RedBlack.BLACK
return blackDepth + 2 if this.color == mugs.RedBlack.DOUBLE_BLACK
return blackDepth if this.color == mugs.RedBlack.RED
return blackDepth - 1 if this.color == mugs.RedBlack.NEGATIVE_BLACK


2 changes: 1 addition & 1 deletion src/TreeSet.coffee
Expand Up @@ -131,7 +131,7 @@ mugs.TreeSet.prototype.update = (index, item) ->
###
mugs.TreeSet.prototype.removeAt = (index) ->
itm = this.get(index)
itm = this.get(index).get()
this.buildFromTree(this.tree.remove(itm))

###*
Expand Down
54 changes: 42 additions & 12 deletions test/RedBlackTree.js
Expand Up @@ -20,7 +20,7 @@ $(document).ready(function(){
e2 = 4,
e3 = 3;

var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), e1, e1, new RedBlackLeaf(BLACK)).insert(e2).insert(e3);
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), e1, e1, new RedBlackLeaf(BLACK)).insert(e2,e2).insert(e3,e3);

ok(tree.containsKey(e1) && tree.containsKey(e2) && tree.containsKey(e3),
"Contains all the right keys");
Expand All @@ -37,7 +37,7 @@ $(document).ready(function(){
e2 = 4,
e3 = 3;

var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), e1, e1, new RedBlackLeaf(BLACK)).insert(e3).insert(e2);
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), e1, e1, new RedBlackLeaf(BLACK)).insert(e3,e3).insert(e2,e2);

ok(tree.containsKey(e1) && tree.containsKey(e2) && tree.containsKey(e3),
"Contains all the right keys");
Expand All @@ -53,7 +53,7 @@ $(document).ready(function(){
e2 = 6,
e3 = 7;

var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), e1, e1, new RedBlackLeaf(BLACK)).insert(e3).insert(e2);
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), e1, e1, new RedBlackLeaf(BLACK)).insert(e3,e3).insert(e2,e2);

ok(tree.containsKey(e1) && tree.containsKey(e2) && tree.containsKey(e3),
"Contains all the right keys");
Expand All @@ -69,7 +69,7 @@ $(document).ready(function(){
e2 = 7,
e3 = 6;

var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), e1, e1, new RedBlackLeaf(BLACK)).insert(e3).insert(e2);
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), e1, e1, new RedBlackLeaf(BLACK)).insert(e3,e3).insert(e2,e2);

ok(tree.containsKey(e1) && tree.containsKey(e2) && tree.containsKey(e3),
"Contains all the right keys");
Expand All @@ -85,7 +85,7 @@ $(document).ready(function(){
e2 = 7,
e3 = 5;

var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), e1, e1, new RedBlackLeaf(BLACK)).insert(e3).insert(e2);
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), e1, e1, new RedBlackLeaf(BLACK)).insert(e3,e3).insert(e2,e2);

ok(tree.containsKey(e1) && tree.containsKey(e2) && tree.containsKey(e3),
"Contains all the right keys");
Expand All @@ -105,13 +105,17 @@ $(document).ready(function(){
});

test("Test that it's possible to remove a key-value pair.", function() {
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), 5,5, new RedBlackLeaf(BLACK)).insert(6);
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), 5,5, new RedBlackLeaf(BLACK)).insert(6,6);
ok(tree.containsKey(6));
ok(!tree.remove(6).containsKey(6));
});

test("Test removal of internal node", function() {
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), 7,7, new RedBlackLeaf(BLACK)).insert(5).insert(8).insert(3).insert(6);
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), 7,7, new RedBlackLeaf(BLACK))
.insert(5,5)
.insert(8,8)
.insert(3,3)
.insert(6,6);

ok(tree.containsKey(8));
ok(tree.containsKey(7));
Expand All @@ -133,7 +137,13 @@ $(document).ready(function(){
});

test("Test removal of external node", function() {
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), 7,7, new RedBlackLeaf(BLACK)).insert(5).insert(8).insert(3).insert(6).remove(5).remove(8);
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), 7,7, new RedBlackLeaf(BLACK))
.insert(5,5)
.insert(8,8)
.insert(3,3)
.insert(6,6)
.remove(5)
.remove(8);
ok(!tree.containsKey(8));
ok(tree.containsKey(7));
ok(tree.containsKey(6));
Expand All @@ -147,7 +157,11 @@ $(document).ready(function(){
});

test("Removal of node with one left child", function() {
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), 7, 7, new RedBlackLeaf(BLACK)).insert(4).insert(3).insert(2).remove(3);
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), 7, 7, new RedBlackLeaf(BLACK))
.insert(4,4)
.insert(3,3)
.insert(2,2)
.remove(3);

ok(tree.containsKey(7));
ok(tree.containsKey(4));
Expand All @@ -161,7 +175,11 @@ $(document).ready(function(){
});

test("Removal of node with one right child", function() {
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), 7,7, new RedBlackLeaf(BLACK)).insert(4).insert(3).insert(8).remove(8);
var tree = new RedBlackNode(RED, new RedBlackLeaf(BLACK), 7,7, new RedBlackLeaf(BLACK))
.insert(4,4)
.insert(3,3)
.insert(8,8)
.remove(8);

ok(tree.containsKey(7));
ok(tree.containsKey(4));
Expand All @@ -175,10 +193,22 @@ $(document).ready(function(){

test("Balance a left negative black node", function() {


// remove 2
// remove 4
});

test("Balance a right negative black node", function() {

test("Balance a right negative black node", function() {
var tree = new RedBlackNode(BLACK,
new RedBlackNode(BLACK,new RedBlackLeaf(BLACK), 1, 1, new RedBlackLeaf(BLACK)),
2,2,
new RedBlackNode(RED,
new RedBlackNode(BLACK,new RedBlackLeaf(BLACK),3,3,new RedBlackLeaf(BLACK)),
4,4,
new RedBlackNode(BLACK,new RedBlackLeaf(BLACK),5,5,new RedBlackLeaf(BLACK))));
var tree2 = tree.remove(2);
ok(tree2.check_() > 0);
// TODO: Add a check metod to the tree
});

});

0 comments on commit 01d93e5

Please sign in to comment.