blob: 4a13d8456c5cc1d55e1cdbbed177e9935aa0a23f [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
};