      1 var define = require("../define").define,
      2         Tree = require("./Tree"),
      3         base = require("../base"),
      4         multiply = base.string.multiply;
      5
      6 var RED = "red", BLACK = "black";
      7
      8
      9 var nil = {level : 0, data : null};
     10
     11 var makeNode = function(data, level) {
     12     return {
     13         data : data,
     14         level : level,
     15         left : nil,
     16         right : nil
     17     }
     18 };
     19
     20 var skew = function(root) {
     21     if (root.level != 0 && root.left.level == root.level) {
     22         var save = root.left;
     23         root.left = save.right;
     24         save.right = root;
     25         root = save;
     26     }
     27     return root;
     28 };
     29
     30 var split = function(root) {
     31     if (root.level != 0 && root.right.right.level == root.level) {
     32         var save = root.right;
     33         root.right = save.left;
     34         save.left = root;
     35         root = save;
     36         ++root.level;
     37     }
     38     return root;
     39 };
     40
     41 var insert = function(root, data, compare) {
     42     if (root == nil) {
     43         root = makeNode(data, 1);
     44     }
     45     else {
     46         var dir = compare(data, root.data) == -1 ? "left" : "right";
     47         root[dir] = insert(root[dir], data, compare);
     48         root = skew(root);
     49         root = split(root);
     50     }
     51     return root;
     52 };
     53
     54 var remove = function(root, data, compare) {
     55     var rLeft, rRight;
     56     if (root != nil) {
     57         var cmp = compare(data, root.data);
     58         if (cmp == 0) {
     59             rLeft = root.left,rRight = root.right;
     60             if (rLeft != nil && rRight != nil) {
     61                 var heir = rLeft;
     62                 while (heir.right != nil)
     63                     heir = heir.right;
     64                 root.data = heir.data;
     65                 root.left = remove(rLeft, heir.data, compare);
     66             } else {
     67                 root = root[rLeft == nil ? "right" : "left"];
     68             }
     69         } else {
     70             var dir = cmp == -1 ? "left" : "right";
     71             root[dir] = remove(root[dir], data, compare);
     72         }
     73     }
     74     if (root != nil) {
     75         var rLevel = root.level;
     76         var rLeftLevel = root.left.level, rRightLevel = root.right.level;
     77         if (rLeftLevel < rLevel - 1 || rRightLevel < rLevel - 1) {
     78             if (rRightLevel > --root.level)
     79                 root.right.level = root.level;
     80
     81             root = skew(root);
     82             root = split(root);
     83         }
     84     }
     85     return root;
     86 };
     87 /**
     88  * @class <p>Andersson Trees are a version of a balanced Binary tree, while similar to RedBlack Trees the balancing is not as strict.</p>
     89  *
     90  * <b>Performance</b>
     91  * <table>
     92  *     <tr><td></td><td>Best</td><td>Worst</td></tr>
     93  *     <tr><td>space</td><td>O(n)</td><td>O(n)</td></tr>
     94  *     <tr><td>Search</td><td>O(log n)</td><td>O(log n)</td></tr>
     95  *     <tr><td>Insert</td><td>O(log n)</td><td>O(log n)</td></tr>
     96  *     <tr><td>Delete</td><td>O(log n)</td><td>O(log n)</td></tr>
     97  * <table>
     98  * @name AnderssonTree
     99  * @augments comb.collections.Tree
    100  * @memberOf comb.collections
    101  */
    102
    103
    104 module.exports = exports = define(Tree, {
    105
    106             instance : {
    107                 /**@lends comb.collections.AnderssonTree.prototype*/
    108
    109                 isEmpty : function() {
    110                     return this.__root == nil || this._super(arguments);
    111                 },
    112
    113                 insert : function(data) {
    114                     if (this.__root == null) this.__root = nil;
    115                     this.__root = insert(this.__root, data, this.compare);
    116                 },
    117
    118                 remove : function(data) {
    119                     this.__root = remove(this.__root, data, this.compare);
    120                 },
    121
    122
    123                 traverseWithCondition : function(node, order, callback) {
    124                     var cont = true;
    125                     if (node != nil) {
    126                         return this._super(arguments);
    127                     }
    128                     return cont;
    129                 },
    130
    131
    132                 traverse : function(node, order, callback) {
    133                     if (node != nil) {
    134                         this._super(arguments);
    135                     }
    136                 },
    137
    138                 contains : function(value) {
    139                     if (this.__root != nil) {
    140                         return this._super(arguments);
    141                     }
    142                     return false;
    143                 },
    144
    145                 __printNode : function(node, level) {
    146                     var str = [];
    147                     if (node.data == null || node == null) {
    148                         str.push(multiply('\t', level));
    149                         str.push("~");
    150                         console.log(str.join(""));
    151                     } else {
    152                         this.__printNode(node.right, level + 1);
    153                         str.push(multiply('\t', level));
    154                         str.push(node.data + ":" + node.level + "\n");
    155                         console.log(str.join(""));
    156                         this.__printNode(node.left, level + 1);
    157                     }
    158                 }
    159
    160             }
    161
    162         });
    163
    164