Subversion Repositories Applications.papyrus

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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