blob: a8b7525b3f81491bdb839d0c077a949ea030e59b [file] [log] [blame]
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.BinaryTree");
dojo.require("dojo.collections.Collections");
dojo.require("dojo.experimental");
dojo.experimental("dojo.collections.BinaryTree");
dojo.collections.BinaryTree = function (data) {
function node(data, rnode, lnode) {
this.value = data || null;
this.right = rnode || null;
this.left = lnode || null;
this.clone = function () {
var c = new node();
if (this.value.value) {
c.value = this.value.clone();
} else {
c.value = this.value;
}
if (this.left) {
c.left = this.left.clone();
}
if (this.right) {
c.right = this.right.clone();
}
};
this.compare = function (n) {
if (this.value > n.value) {
return 1;
}
if (this.value < n.value) {
return -1;
}
return 0;
};
this.compareData = function (d) {
if (this.value > d) {
return 1;
}
if (this.value < d) {
return -1;
}
return 0;
};
}
function inorderTraversalBuildup(current, a) {
if (current) {
inorderTraversalBuildup(current.left, a);
a.add(current);
inorderTraversalBuildup(current.right, a);
}
}
function preorderTraversal(current, sep) {
var s = "";
if (current) {
s = current.value.toString() + sep;
s += preorderTraversal(current.left, sep);
s += preorderTraversal(current.right, sep);
}
return s;
}
function inorderTraversal(current, sep) {
var s = "";
if (current) {
s = inorderTraversal(current.left, sep);
s += current.value.toString() + sep;
s += inorderTraversal(current.right, sep);
}
return s;
}
function postorderTraversal(current, sep) {
var s = "";
if (current) {
s = postorderTraversal(current.left, sep);
s += postorderTraversal(current.right, sep);
s += current.value.toString() + sep;
}
return s;
}
function searchHelper(current, data) {
if (!current) {
return null;
}
var i = current.compareData(data);
if (i == 0) {
return current;
}
if (i > 0) {
return searchHelper(current.left, data);
} else {
return searchHelper(current.right, data);
}
}
this.add = function (data) {
var n = new node(data);
var i;
var current = root;
var parent = null;
while (current) {
i = current.compare(n);
if (i == 0) {
return;
}
parent = current;
if (i > 0) {
current = current.left;
} else {
current = current.right;
}
}
this.count++;
if (!parent) {
root = n;
} else {
i = parent.compare(n);
if (i > 0) {
parent.left = n;
} else {
parent.right = n;
}
}
};
this.clear = function () {
root = null;
this.count = 0;
};
this.clone = function () {
var c = new dojo.collections.BinaryTree();
c.root = root.clone();
c.count = this.count;
return c;
};
this.contains = function (data) {
return this.search(data) != null;
};
this.deleteData = function (data) {
var current = root;
var parent = null;
var i = current.compareData(data);
while (i != 0 && current != null) {
if (i > 0) {
parent = current;
current = current.left;
} else {
if (i < 0) {
parent = current;
current = current.right;
}
}
i = current.compareData(data);
}
if (!current) {
return;
}
this.count--;
if (!current.right) {
if (!parent) {
root = current.left;
} else {
i = parent.compare(current);
if (i > 0) {
parent.left = current.left;
} else {
if (i < 0) {
parent.right = current.left;
}
}
}
} else {
if (!current.right.left) {
if (!parent) {
root = current.right;
} else {
i = parent.compare(current);
if (i > 0) {
parent.left = current.right;
} else {
if (i < 0) {
parent.right = current.right;
}
}
}
} else {
var leftmost = current.right.left;
var lmParent = current.right;
while (leftmost.left != null) {
lmParent = leftmost;
leftmost = leftmost.left;
}
lmParent.left = leftmost.right;
leftmost.left = current.left;
leftmost.right = current.right;
if (!parent) {
root = leftmost;
} else {
i = parent.compare(current);
if (i > 0) {
parent.left = leftmost;
} else {
if (i < 0) {
parent.right = leftmost;
}
}
}
}
}
};
this.getIterator = function () {
var a = [];
inorderTraversalBuildup(root, a);
return new dojo.collections.Iterator(a);
};
this.search = function (data) {
return searchHelper(root, data);
};
this.toString = function (order, sep) {
if (!order) {
var order = dojo.collections.BinaryTree.TraversalMethods.Inorder;
}
if (!sep) {
var sep = " ";
}
var s = "";
switch (order) {
case dojo.collections.BinaryTree.TraversalMethods.Preorder:
s = preorderTraversal(root, sep);
break;
case dojo.collections.BinaryTree.TraversalMethods.Inorder:
s = inorderTraversal(root, sep);
break;
case dojo.collections.BinaryTree.TraversalMethods.Postorder:
s = postorderTraversal(root, sep);
break;
}
if (s.length == 0) {
return "";
} else {
return s.substring(0, s.length - sep.length);
}
};
this.count = 0;
var root = this.root = null;
if (data) {
this.add(data);
}
};
dojo.collections.BinaryTree.TraversalMethods = {Preorder:1, Inorder:2, Postorder:3};