geofstone / LLRB-Binary-Search-Tree-JS

Left-Leaning, Red-Black Binary Search Tree in JavaScript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

LLRB-Binary-Search-Tree-JS

A Left-Leaning, Red-Black Binary Search Tree implemented in JavaScript!

Example printable output:

15 27 62 114 369 406 446 492 498 506 771 773 776 937 954 1003 1158 1161 1204 1285 1297 1494 1594 1597 1628 1690 1848 2395 2572 2670 2748 2801 2874 3119 3146 3227 3244 3340 3362 3464 3729 3801 3957 4011 4275 4303 4630 4760 4799 4806 4947 5042 5080 5141 5295 5499 5569 5630 5716 5734 5758 5873 5994 6200 6435 6644 6875 6904 6932 7010 7098 7145 7235 7239 7500 7573 7742 7925 7984 8003 8165 8185 8368 8693 8701 8738 8891 9017 9084 9195 9279 9372 9435 9461 9490 9514 9580 9585 9896 9967

4630 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: null
├ 7573 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 4630
│ ├ 9084 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 7573
│ │ ├ 9461 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 9084
│ │ │ ├ 9580 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 9461
│ │ │ │ ├ 9896 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 9580
│ │ │ │ │ ╞ leaf
│ │ │ │ │ └ 9585 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 9896
│ │ │ │ └ 9514 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 9580
│ │ │ │   ╞ leaf
│ │ │ │   └ 9490 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 9514
│ │ │ └ 9372 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 9461
│ │ │   ├ 9435 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 9372
│ │ │   └ 9279 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 9372
│ │ │     ╞ leaf
│ │ │     └ 9195 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 9279
│ │ └ 8185 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 9084
│ │   ├ 8891 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 8185
│ │   │ ├ 9017 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 8891
│ │   │ └ 8701 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 8891
│ │   │   ├ 8738 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 8701
│ │   │   └ 8693 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 8701
│ │   │     ╞ leaf
│ │   │     └ 8368 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 8693
│ │   └ 7984 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 8185
│ │     ├ 8165 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 7984
│ │     │ ╞ leaf
│ │     │ └ 8003 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 8165
│ │     └ 7925 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 7984
│ │       ╞ leaf
│ │       └ 7742 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 7925
│ └ 6435 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 7573
│   ├ 7098 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 6435
│   │ ├ 7235 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 7098
│   │ │ ├ 7500 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 7235
│   │ │ │ ╞ leaf
│   │ │ │ └ 7239 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 7500
│   │ │ └ 7145 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 7235
│   │ └ 6932 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 7098
│   │   ├ 7010 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 6932
│   │   └ 6875 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 6932
│   │     ├ 6904 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 6875
│   │     └ 6644 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 6875
│   └ 5569 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 6435
│     ├ 5873 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 5569
│     │ ├ 6200 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 5873
│     │ │ ╞ leaf
│     │ │ └ 5994 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 6200
│     │ └ 5716 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 5873
│     │   ├ 5758 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 5716
│     │   │ ╞ leaf
│     │   │ └ 5734 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 5758
│     │   └ 5630 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 5716
│     └ 5042 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 5569
│       ├ 5141 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 5042
│       │ ├ 5499 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 5141
│       │ │ ╞ leaf
│       │ │ └ 5295 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 5499
│       │ └ 5080 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 5141
│       └ 4799 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 5042
│         ├ 4947 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 4799
│         │ ╞ leaf
│         │ └ 4806 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 4947
│         └ 4760 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 4799
└ 1848 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 4630
  ├ 3227 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 1848
  │ ├ 3801 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 3227
  │ │ ├ 4011 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 3801
  │ │ │ ├ 4303 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 4011
  │ │ │ │ ╞ leaf
  │ │ │ │ └ 4275 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 4303
  │ │ │ └ 3957 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 4011
  │ │ └ 3362 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 3801
  │ │   ├ 3729 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 3362
  │ │   │ ╞ leaf
  │ │   │ └ 3464 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 3729
  │ │   └ 3340 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 3362
  │ │     ╞ leaf
  │ │     └ 3244 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 3340
  │ └ 2801 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 3227
  │   ├ 3119 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 2801
  │   │ ├ 3146 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 3119
  │   │ └ 2874 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 3119
  │   └ 2572 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 2801
  │     ├ 2748 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 2572
  │     │ ╞ leaf
  │     │ └ 2670 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 2748
  │     └ 2395 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 2572
  └ 1003 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 1848
    ├ 1494 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 1003
    │ ├ 1597 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 1494
    │ │ ├ 1690 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 1597
    │ │ │ ╞ leaf
    │ │ │ └ 1628 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 1690
    │ │ └ 1594 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 1597
    │ └ 1285 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 1494
    │   ├ 1297 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 1285
    │   └ 1161 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 1285
    │     ├ 1204 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 1161
    │     └ 1158 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 1161
    └ 506 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 1003
      ├ 776 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 506
      │ ├ 954 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 776
      │ │ ╞ leaf
      │ │ └ 937 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 954
      │ └ 773 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 776
      │   ╞ leaf
      │   └ 771 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 773
      └ 406 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 506
        ├ 492 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 406
        │ ├ 498 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 492
        │ └ 446 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 492
        └ 114 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 406
          ├ 369 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 114
          └ 62 - - - - - - - - [1] - - - - - - - - (B) - - - - - - - - Parent: 114
            ╞ leaf
            └ 27 - - - - - - - - [1] - - - - - - - - (R) - - - - - - - - Parent: 62

About

This implementation supports lots of advanced functionality like:

  • storing both keys and values (values do not affect default functionality or sorting)
  • storing duplicate values (if enabled, all values go into an array for each node)
  • traversing to the predecessor or successor of any node (in sorted order)
    • bidirectional iteration that does not involve any stacks/arrays and is fast (unlike other implementations out there)
  • finding a node with a given key or returning null if there is none
  • finding the nearest node to a key
  • using a custom sorting function (read the code comments regarding this one)
  • getting the first and last nodes of a tree or subtree
  • printing an entire tree, or even a subtree, as text

It performs at roughly the same speed as a sorted array (because it's JS - the code itself is relatively fast...); but, note that it doesn't need to constantly be resorted, like an array would!


How to Use

//Create a new Left-Leaning, Red-Black Binary Search Tree.
let tree = new BinarySearchTree({
    //compareFunction: function(a, b) { return a - b; },
    allowDuplicates: true
});

//Insert a bunch of key->value pairs.
let insertedNode;
for (let x = 0; x < 100000; ++x) {
    //Random key->value pair.
    insertedNode = tree.insert(Math.round(Math.random() * 10000), Math.random().toFixed(2));
}
//Get the last inserted node (or the existing node with multiple values).
tree.nodeInsertedInto == insertedNode;

//Remove nodes with specific keys, if they exist.
for (let removeIndex = 0; removeIndex < 10000; ++removeIndex) {
    tree.remove(Math.round(Math.random() * 10000));
}

//Remove values at the beginning or end.
for (let x = 0; x < 100; ++x) {
    tree.removeMin();
    tree.removeMax();
}

//Insert a bunch more key->value pairs.
for (let x = 0; x < 100000; ++x) {
    //Random key->value pair.
    tree.insert(Math.round(Math.random() * 10000), Math.random().toFixed(2));
}

//See if a node with key 100 is in the tree. Returns `null` if it can't find it.
let findResult = tree.find(100);
//Find a node with key 100; or, if there is none, find the nearest node (based on key).
//Guaranteed to not be `null` unless the tree is empty.
findResult = tree.findNearest(100);
//Access a node's key and value.
findResult.key;
findResult.value;

//Get a node's predecessor or successor (can be called until
//it reaches `null` on either end of the tree).
//Note: This is bidirection-capable!
let neighbor = BinarySearchTree.getPredecessor(findResult);
neighbor = BinarySearchTree.getSuccessor(findResult);
//Access a node's key and value.
neighbor.key;
neighbor.value;

//Get the first and last nodes of a tree or a subtree (pass in a node).
let first = BinarySearchTree.getFirstNode(tree.root);
let last = BinarySearchTree.getLastNode(tree.root);

//Clear/Reset the tree.
tree.clear();
//Determine if the tree is empty/cleared.
tree.isEmpty();

See test.js for more examples of its usage, including some sorted array comparison testing and benchmarking code.


Special thanks:

About

Left-Leaning, Red-Black Binary Search Tree in JavaScript

License:The Unlicense


Languages

Language:JavaScript 99.0%Language:HTML 1.0%