initial commit

This commit is contained in:
Mahdi Dibaiee
2015-07-24 11:14:18 +04:30
commit a7e7ca0350
916 changed files with 101220 additions and 0 deletions

View File

@ -0,0 +1,95 @@
'use strict';
import _ from '../utils';
class Node {
constructor(value) {
this.value = value;
this.right = null;
this.left = null;
}
}
class BinaryTree {
constructor(value) {
this.root = new Node(value);
this.length = 1;
}
search(key, node = this.root) {
if (!node || node.value === key) {
return node;
} else if (node.value > key) {
return this.search(key, node.left);
} else {
return this.search(key, node.right);
}
}
insert(value, node = this.root, parent = null, dir) {
if (!node) {
parent[dir] = new Node(value);
} else if (node.value > value) {
this.insert(value, node.left, node, 'left');
} else {
this.insert(value, node.right, node, 'right');
}
}
remove(value, node = this.root, parent = null) {
if (!node) {
return null;
}
// specified parent means we're recursing to delete, and
// checking has been already done
if (node.value === value || parent) {
// number of children, !! converts to boolean, + converts to number
// false yields 0, true yields 1
const children = +!!node.left + +!!node.right;
if (!children) {
parent.right = null;
} else if (children === 1) {
node = node.left || node.right;
} else {
node.value = node.right.value;
return this.remove(value, node.right, node, true);
}
} else if (node.value > value) {
return this.remove(value, node.left);
} else {
return this.remove(value, node.right);
}
}
// in-order
traverse(cb, node = this.root) {
if (!node) {
return;
}
// left
this.traverse(cb, node.left);
// parent
cb(node.value);
// right
this.traverse(cb, node.right);
}
}
let test = new BinaryTree(10);
test.insert(6);
test.insert(18);
test.insert(4);
test.insert(8);
test.insert(15);
test.insert(21);
_.inspect(test);
_.log('Traverse: ');
test.traverse(value => {
_.print(value + ' ');
});

View File

@ -0,0 +1,144 @@
'use strict';
import _ from '../utils';
export class Node {
constructor(value, next = null) {
this.value = value;
this.next = next;
}
}
export class List {
constructor(root) {
this.root = root;
this.length = 1;
}
append(value) {
let node = this.root;
while (node.next !== null) {
node = node.next;
}
this.length++;
let newNode = new Node(value);
node.next = newNode;
return newNode;
}
delete(value, node = this.root) {
if (node === this.root && node.value === value) {
this.root = this.root.next;
return;
}
while (node.next) {
if (node.next.value === value) {
node.next = node.next.next;
this.length--;
}
node = node.next;
}
}
// Cracking the Coding Interview challenges
deleteDuplicates() {
let node = this.root;
do {
this.delete(node.value, node.next);
node = node.next;
} while (node.next !== null)
}
last(n) {
let target = this.length - n;
let i = 0;
let node = this.root;
while (i < target && node.next !== null) {
node = node.next;
i++;
}
return node;
}
partition(x) {
let less = [],
greater = [];
let node = this.root;
while (node !== null) {
if (node.value < x) {
less.push(node.value);
} else {
greater.push(node.value);
}
node = node.next;
}
this.root = new Node(less[0]);
less.slice(1).concat(greater).reduce((a, b) => {
a.next = new Node(b);
return a.next;
}, this.root);
}
}
// Cracking the Coding Interview 2.5
// Numbers are reversed (617 == 7 -> 1 -> 6 )
const addLists = (first, last) => {
let num = 0;
let nodes = [first.root, last.root];
let place = 1;
while (nodes[0] !== null) {
let currentSum = (nodes[0].value + nodes[1].value) * place;
place *= 10;
num += currentSum;
nodes = [nodes[0].next, nodes[1].next];
}
return num;
};
let test = new List(new Node(10, new Node(5)));
test.append(20);
test.append(8);
test.delete(10);
test.delete(20);
// Test deleteDuplicates
test.append(21);
let testNode = test.append(32);
test.append(21);
test.append(42);
test.append(21);
test.append(7);
test.deleteDuplicates();
// Test last-nth
_.log(test.last(2).value === 42);
// Test partition
_.log('Partition around 8');
test.partition(8);
_.log('Sum 7 -> 1 -> 6 AND 5 -> 9 -> 2');
let n1 = new List(new Node(7, new Node(1, new Node(6))));
let n2 = new List(new Node(5, new Node(9, new Node(2))));
_.log(addLists(n1, n2) === 912);
_.inspect(test);

View File

@ -0,0 +1,11 @@
import chai from 'chai';
import {Node, List} from '../linked-lists';
chai.should();
test('Constructing new Lists', () => {
let list = new List(new Node(10, new Node(5)));
list.root.value.should.equal(10);
list.root.next.value.should.equal(5);
});

View File

@ -0,0 +1,38 @@
import chai from 'chai';
import {Node, Trie} from '../trie';
chai.should();
test('Construct new Trie', () => {
let trie = new Trie();
trie.root.children.length.should.equal(0);
});
test('Add new parent values', () => {
let trie = new Trie();
trie.add('a');
trie.add('b');
trie.add('c');
trie.add('t');
trie.root.children.length.should.equal(4);
});
test('Adding values with existing parents', () => {
let trie = new Trie();
trie.add('a');
trie.add('ab');
trie.add('aba');
trie.add('abas');
let parent = trie.root;
for (let i = 0; i < 3; i++) {
parent.children.length.should.equal(1);
parent = parent.children[0];
}
parent.children.length.should.equal(0);
});

28
data-structures/trie.js Normal file
View File

@ -0,0 +1,28 @@
'use strict';
import _ from '../utils';
export class Node {
constructor(value) {
this.value = value;
this.children = [];
}
}
export class Trie {
constructor() {
this.root = new Node();
}
add(value, node = this.root, iteration = 0) {
let parent = node.children.find(n => {
return n.value[iteration] === value[iteration];
});
if (parent) {
this.add(value, parent, iteration + 1);
} else {
node.children.push(new Node(value));
}
}
}