      1 var define = require("../define").define,
      2         Tree = require("./Tree"),
      3         base = require("../base");
      4
      5 /**
      6  * @class <p>A Search tree that maintains the following properties</p>
      7  * <ul>
      8  *     <li>The left subtree of a node contains only nodes with keys less than the node's key.
      9  *     <li>The right subtree of a node contains only nodes with keys greater than the node's key.
     10  *     <li>Both the left and right subtrees must also be binary search trees.
     11  * </ul>
     12  *
     13  * <b>Performance</b>
     14  * <table>
     15  *     <tr><td></td><td>Best</td><td>Worst</td></tr>
     16  *     <tr><td>Space</td><td>O(n)</td><td>O(n)</td></tr>
     17  *     <tr><td>Search</td><td>O(log n)</td><td>O(n)</td></tr>
     18  *     <tr><td>Insert</td><td>O(log n)</td><td>O(n)</td></tr>
     19  *     <tr><td>Delete</td><td>O(log n)</td><td>O(n)</td></tr>
     20  * <table>
     21  * @name BinaryTree
     22  * @augments comb.collections.Tree
     23  * @memberOf comb.collections
     24  */
     25 module.exports = exports = define(Tree, {
     26     instance : {
     27         /**@lends comb.collections.BinaryTree.prototype*/
     28
     29         insert : function(data) {
     30             if (this.__root == null) {
     31                 return (this.__root = {
     32                     data : data,
     33                     parent : null,
     34                     left : null,
     35                     right : null
     36                 });
     37             }
     38             var compare = this.compare;
     39             var root = this.__root;
     40             while (root != null) {
     41                 var cmp = compare(data, root.data);
     42                 if (cmp) {
     43                     var leaf = (cmp == -1) ? "left" : "right";
     44                     var next = root[leaf];
     45                     if (next == null) {
     46                         return (root[leaf] = {data : data, parent : root, left : null, right : null});
     47                     } else {
     48                         root = next;
     49                     }
     50                 } else {
     51                     return;
     52                 }
     53             }
     54         },
     55
     56         remove : function(data) {
     57             if (this.__root != null) {
     58                 var head = {right : this.__root}, it = head;
     59                 var p, f = null;
     60                 var dir = "right";
     61                 while (it[dir] != null) {
     62                     p = it;
     63                     it = it[dir];
     64                     var cmp = this.compare(data, it.data);
     65                     if (!cmp) {
     66                         f = it;
     67                     }
     68                     dir = (cmp == -1 ? "left" : "right");
     69                 }
     70                 if (f != null) {
     71                     f.data = it.data;
     72                     p[p.right == it ? "right" : "left"] = it[it.left == null ? "right" : "left"];
     73                 }
     74                 this.__root = head.right;
     75             }
     76
     77         }
     78     }
     79 });
     80
     81
     82