Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
3162105
Initial commit
diop May 15, 2017
7cc5606
Fix README
diop May 15, 2017
7e01753
Added installation and setup to README file and deleted advanced sect…
jrpool May 15, 2017
eb0b738
Merge pull request #1 from diop/poolwork
diop May 15, 2017
99dafb7
Wrote and began testing PriorityNode class.
jrpool May 16, 2017
5298386
Merge pull request #2 from diop/poolwork
diop May 16, 2017
974bf6c
Added tests and organized them into contexts.
jrpool May 16, 2017
3f440fb
Merge pull request #3 from diop/poolwork
diop May 16, 2017
4c1716e
add node class
diop May 16, 2017
b55ac74
Merge branch 'master' into node-class
diop May 16, 2017
7fb584c
add node test
diop May 16, 2017
8f6f767
Merge pull request #4 from diop/node-class
jrpool May 16, 2017
e680b6a
Added tests for getData and made test format more compact.
jrpool May 16, 2017
4258a8b
Merge branch 'master' into poolwork
jrpool May 16, 2017
efbd2ae
Merge pull request #5 from diop/poolwork
diop May 16, 2017
ade14d2
Added checks in constructor for invalid and incomplete argument and a…
jrpool May 16, 2017
7c539b1
Merge pull request #6 from diop/poolwork
diop May 16, 2017
382ec8a
Added check and tests for next property of constructor argument.
jrpool May 16, 2017
726e7f8
Merge pull request #7 from diop/poolwork
diop May 16, 2017
efe25b7
Added tests for getNext.
jrpool May 16, 2017
9d793ba
Merge pull request #8 from diop/poolwork
diop May 16, 2017
b76e838
Changed syntax of instanceof invocations. Added setNext tests.
jrpool May 16, 2017
74997db
add linkedlist class and test
diop May 16, 2017
c077631
Reorganized tests to create class instances for any context inside it.
jrpool May 16, 2017
4b65525
Merge pull request #9 from diop/poolwork
diop May 16, 2017
5f63b73
update linledlist test
diop May 17, 2017
193e7fa
Finished implementing, testing, and debugging priorityQueue class.
jrpool May 17, 2017
cd6e765
Merge pull request #10 from diop/poolwork
diop May 17, 2017
e2cc862
reset linked list tests
diop May 17, 2017
79ff910
pass insert and getHead tests
diop May 17, 2017
b19505f
pass insert and getHead tests
diop May 17, 2017
77ab88c
pass contains test
diop May 17, 2017
4811431
update linkedlist test
diop May 17, 2017
db9e134
pass find text
diop May 17, 2017
5d35833
pass insertFirst test
diop May 17, 2017
bf1c492
pass insertBefore test
diop May 18, 2017
abea694
Changed mocha function syntax from => per mocha recommendation. Creat…
jrpool May 18, 2017
0bff4f6
Created tests for set interrogation (not yet set manipulation).
jrpool May 18, 2017
aa33baa
pass all tests except insertAfter
diop May 18, 2017
ddfece1
Merge pull request #11 from diop/poolwork
diop May 18, 2017
96dbeeb
all tests passing
diop May 18, 2017
55e4ca0
Merge pull request #12 from diop/linkedlist-class
jrpool May 18, 2017
2610d76
Renamed Set to PowerSet to avoid conflict with JS Set built-in. Finis…
jrpool May 18, 2017
45759be
Merge pull request #13 from diop/poolwork
diop May 18, 2017
d54119a
pass all tests
diop May 18, 2017
b9053a7
pass all stack tests
diop May 18, 2017
dd99537
Merge pull request #14 from diop/stack-class
jrpool May 18, 2017
b0017aa
Developed, tested, and debugged Node2 and Queue2 (Pool versions of No…
jrpool May 18, 2017
17c61de
Merge pull request #15 from diop/poolwork
diop May 19, 2017
6e6dcda
Created, tested, and debugged Stack2 (Pool version of Stack).
jrpool May 19, 2017
8c5f115
Created, tested, and debugged LinkedList2 (Pool version of LinkedList).
jrpool May 19, 2017
1436e1f
Merge pull request #16 from diop/poolwork
diop May 19, 2017
e3d2fb8
Cleanup and parking of linked_list3.
jrpool May 19, 2017
304baae
Merge pull request #17 from diop/poolwork
diop May 19, 2017
469b962
Made file names consistent, merged stack1, finished readme file.
jrpool May 19, 2017
1eb54bc
Parked stack1 for further work. Made linting corrections.
jrpool May 19, 2017
409e677
Merge pull request #18 from diop/poolwork
diop May 19, 2017
8f487e2
Added explanatory comments to README file.
jrpool May 19, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
node_modules/
.DS_Store
extras/
44 changes: 40 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,48 @@

Tests and implementations for common data structures. See the full list in the [data-structures.md](data-structures.md) file.

Base repository for the [Core Data Structures](http://jsdev.learnersguild.org/goals/128) goal.
Project Goal: [Core Data Structures - Basic](http://jsdev.learnersguild.org/goals/156-Core_Data_Structures-Basic.html)

Base repository: [Core Data Structures--Basic](https://github.com/diop/core-data-structures)

Team Name: ten-seal

Project Members:

[Jonathan Pool](https://github.com/jrpool)

[Fodé Diop](https://github.com/diop)

## Installation and Setup

_Fill this out_
0. These instructions presuppose that npm (https://nodejs.org/en/) is installed.

1. Clone this repository into a local directory.

2. In the local directory, install required dependencies (see package.json) by executing:

npm i

3. In the local directory, perform the provided tests by executing:

npm test

4. Install ESLint (http://eslint.org) by executing:

npm install -gS eslint

cd

eslint --init

5. Edit .eslintrc.json in your home directory to customize.

## Comments

Each structure implementation in this repository relies on one of two features: (1) the next property of Node objects or the next and previous properties of DoubleNode objects, or (2) the properties and methods of JavaScript Array or Set objects.

Some data structures are implemented twice in this repository. Where this is the case, they are named with “1” and “2” suffixes. A structure implementation with “1” relies on Node or DoubleNode properties; one with “2” relies on Array or Set properties and methods.

## Usage and Examples
The Node object has two implementations differing in internal validation, each with its own tests.

_...and this_
The Set implementation is named “PowerSet” so as to avoid any confusion with JavaScript Set objects.
81 changes: 0 additions & 81 deletions data-structures.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,87 +156,6 @@ set.clone() // returns a cloned set.

_Note: if you haven't worked with sets before, you may want to read about [sets](https://www.mathsisfun.com/sets/sets-introduction.html) and [subsets](https://www.mathsisfun.com/activity/subsets.html)._

## Advanced Data Structures

### Hash Table ( using a LinkedList for collision chaining )

Maps keys to values, like a dictionary or a phone book. Or an object in JavaScript...

From [Wikipedia](https://en.wikipedia.org/wiki/Hash_table) [edited]:

> A data structure used to implement an associative array, a structure that can map keys to values. A hash table uses a hash function to compute an index into an array of _buckets_ or _slots_, from which the desired value can be found.

Collision Chaining: [Wikipedia](http://www.cs.rmit.edu.au/online/blackboard/chapter/05/documents/contribute/chapter/05/chaining.html)
> Instead of storing the data directly inside the structure, have a linked list structure at each hash element. That way, all the collision, retrieval and deletion functions can be handled by the list, and the hash function's role is limited mainly to that of a guide to the algorithms, as to which hash element's list to operate on.

```javascript
const ht = new HashTable()
ht.put("name", "Zanzibar") // adds a key-value pair to the hash table, deal with collisions using chaining
ht.get("name") // returns the data associated with key.
ht.contains("name") // returns true if the hash table contains the key.
ht.iterate((k, v) => console.log(`${k}: ${v}`)) // takes a callback function and passes it each key and value in sequence.
ht.remove("name") // removes a key-value pair by key.
ht.size() // returns the number of key-value pairs in the hash table.
HashTable.hash("name") // generates a hash for the key "name"
```

### Binary (Search) Tree

A sorted binary tree for fast lookup, addition and removal of items.

From [Wikipedia](https://en.wikipedia.org/wiki/Binary_search_tree) [edited]:

> A particular type of container that allows fast lookup, addition and removal of items, and can be used to implement either dynamic sets of items, or lookup tables that allow finding an item by its key (e.g., finding the phone number of a person by name).
>
> Binary search trees keep their keys in sorted order, so that lookup and other operations can use the principle of binary search: when looking for a key in a tree (or a place to insert a new key), they traverse the tree from root to leaf, making comparisons to keys stored in the nodes of the tree and deciding, based on the comparison, to continue searching in the left or right subtrees.

```javascript
const bst = new BinarySearchTree()
bst.insert(3) // inserts a node with the specified value into the tree.
bst.search(3) // returns a node object or null if not found.
bst.remove(3) // removes an value's node (if exists) from the tree.
bst.traverse((val) => console.log(val)) // traverse the tree using in-order traversal and apply function on each node's value.
bst.count() // return the number of nodes in the tree.
```

#### Tree Node

To implement a _standard_ binary search tree, use a **tree node** data structure in your implementation. Use this interface as a reference:

```javascript
const leastNode = new TreeNode({data: 3})
const moreNode = new TreeNode({data: 10})
const midNode = new TreeNode({data: 7, left: leastNode, right: moreNode})

midNode.getData() // returns the node's data
midNode.getLeft() // returns the left node or null if none
midNode.setLeft(leastNode) // changes the reference to the left node and returns the original node
midNode.getRight() // returns the right node or null if none
midNode.setRight(moreNode) // changes the reference to the right node and returns the original node
```

### Directed Graph

Nodes connected by vertices with a direction.

From [Wikipedia](https://en.wikipedia.org/wiki/Directed_graph) [edited]:

> A graph (that is a set of vertices connected by edges), where the edges have a direction associated with them.

```javascript
const diGraph = new DirectedGraph()
diGraph.addVertex('v1') // adds a vertex to the graph.
diGraph.hasVertex('v1') // returns true if the graph contains the vertex or false if not.
diGraph.addDirection('v1', 'v2') // adds a direction from 'v1' to 'v2'.
diGraph.hasDirection('v1', 'v2') // returns true if there's a direction from 'v1' to 'v2'.
diGraph.visit('v1', vertex => console.log(vertex)) // visit all the connected vertices in the graph starting with v1 and apply function on the reached vertex.
diGraph.findPaths('v1', 'v2') // returns an array of all the paths between two vertices.
diGraph.removeDirection('v1', 'v2') // removes an existing direction between 'v1' and 'v2'.
diGraph.getSeparatedVertices() // returns an array of all the vertices that are unconnected to the graph (have no direction linking them to another vertex).
diGraph.removeVertex('v1') // removes an existing vertex and all its directions (the incoming and outgoing).
diGraph.count() // returns the number of vertices in the graph.
```

### Sources

Most of the above was shamelessly borrowed from Wikipedia and these libraries:
Expand Down
15 changes: 12 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
{
"name": "core-data-structures",
"description": "Tests and implementations for common data structures.",
"description": "Tests and implementations for basic core data structures.",
"private": false,
"version": "0.0.0",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/diop/core-data-structures"
},
"dependencies": {
"babel-preset-es2015": "^6.24.1",
"babel-register": "^6.24.1"
},
"devDependencies": {
"babel-cli": "^6.18.0",
"babel-preset-env": "^1.1.4",
"babel-register": "^6.18.0",
"chai": "~1.8.0",
"chai": "^1.8.1",
"chai-change": "^2.1.2",
"mocha": "2.0.1"
"mocha": "^2.0.1"
},
"scripts": {
"build": "babel src -d lib",
Expand Down
211 changes: 211 additions & 0 deletions spec/double_node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
import chai, { expect } from 'chai'
import chaiChange from 'chai-change'
import DoubleNode from '../src/double_node'

chai.use(chaiChange)

describe('DoubleNode', function() {
'use strict'

it('is a function', function() {
expect(DoubleNode).to.be.a('function')
})

context('getData()', function() {
const dsNode = new DoubleNode({data: 'string'})
const dnNode = new DoubleNode({data: 0})
const daNode = new DoubleNode({data: [1, 2]})
const doNode = new DoubleNode({data: {'a': 1, 'b': 2}})
const emptyNode = new DoubleNode()
const ngNode = new DoubleNode({data: 1, next: dsNode})
const nbNode = new DoubleNode({data: 2, next: "dnNode"})
const pgNode = new DoubleNode({data: 3, previous: dnNode})
const pgbNode = new DoubleNode({data: 4, previous: emptyNode})
it('returns the correct type, if a string', function() {
expect(dsNode.getData()).to.be.a('string')
})
it('returns the correct value, if a string', function() {
expect(dsNode.getData()).to.be.equal('string')
})
it('returns the correct type, if a number', function() {
expect(dnNode.getData()).to.be.a('number')
})
it('returns the correct value, if a number', function() {
expect(dnNode.getData()).to.be.equal(0)
})
it('returns the correct type, if an array', function() {
expect(Array.isArray(daNode.getData())).to.be.true
})
it('returns the correct value, if an array', function() {
expect(daNode.getData()).to.be.deep.equal([1, 2])
})
it('returns the correct type, if an object', function() {
expect(doNode.getData()).to.be.an('object')
})
it('returns the correct value, if an object', function() {
expect(doNode.getData()).to.be.deep.equal({'a': 1, 'b': 2})
})
it('returns an object with a retrievable property, if an object', function() {
expect(doNode.getData().a).to.be.equal(1)
})
it('returns the correct value, if next is specified', function() {
expect(ngNode.getData()).to.be.equal(1)
})
it('returns the correct value, if previous is specified', function() {
expect(pgNode.getData()).to.be.equal(3)
})
it('returns the correct value, if previous is a bad DoubleNode', function() {
expect(pgbNode.getData()).to.be.equal(4)
})
it('returns undefined, if unspecified', function() {
expect(emptyNode.getData()).to.be.undefined
})
it('returns undefined, if next is not a DoubleNode', function() {
expect(nbNode.getData()).to.be.undefined
})
})

context('getNext()', function() {
const nnNode = new DoubleNode({data: 'string'})
const ngNode = new DoubleNode({data: 0, next: nnNode})
const nbNode = new DoubleNode({data: 1, next: 0})
const dxnbNode = new DoubleNode({next: ngNode})
const ngbNode = new DoubleNode({data: 0, next: dxnbNode})
const pgNode = new DoubleNode({data: 2, next: nnNode, previous: nnNode})
const pgbNode = new DoubleNode({data: 3, next: ngNode, previous: nbNode})
const pbNode = new DoubleNode({data: 4, next: ngNode, previous: "node"})
it('returns the correct type, if specified', function() {
expect(ngNode.getNext() instanceof DoubleNode).to.be.true
})
it('returns the correct value, if specified', function() {
expect(ngNode.getNext()).to.be.deep.equal(nnNode)
})
it(
'returns a DoubleNode with a retrievable property, if specified',
function() {
expect(ngNode.getNext().getData()).to.be.equal('string')
}
)
it('returns null, if unspecified', function() {
expect(nnNode.getNext()).to.be.null
})
it('returns null, if specified but not a DoubleNode', function() {
expect(nbNode.getNext()).to.be.null
})
it('returns null, if specified but data is unspecified', function() {
expect(dxnbNode.getNext()).to.be.null
})
})

context('setNext()', function() {
const nnNode = new DoubleNode({data: 0})
const ngNode = new DoubleNode({data: 'string', next: nnNode})
const nbNode = new DoubleNode({data: 1, next: "nonode"})
const pbNode = new DoubleNode({data: 2, next: ngNode, previous: "bad"})
it('returns a DoubleNode', function() {
expect(nnNode.setNext(ngNode) instanceof DoubleNode).to.be.true
})
it('returns the correct DoubleNode', function() {
expect(nnNode.setNext(ngNode)).to.be.deep.equal(nnNode)
})
it(
'returns a DoubleNode with a retrievable data property',
function() {
expect(ngNode.setNext(nnNode).getData()).to.be.equal('string')
}
)
it(
'returns a DoubleNode with a retrievable good new next property',
function() {
expect(nnNode.setNext(ngNode).getNext()).to.be.deep.equal(ngNode)
}
)
it(
'returns a DoubleNode with a retrievable bad new next property',
function() {
expect(nnNode.setNext(nbNode).getNext()).to.be.deep.equal(nbNode)
}
)
it(
'fails to change next (from last value), if newNext is invalid',
function() {
expect(nnNode.setNext("badNode").getNext()).to.be.deep.equal(nbNode)
}
)
})

context('getPrevious()', function() {
const nnNode = new DoubleNode({data: 'astring'})
const ngNode = new DoubleNode({data: 0, next: nnNode})
const nbNode = new DoubleNode({data: 1, next: 0})
const dxpbNode = new DoubleNode({previous: ngNode})
const pgNode = new DoubleNode({data: 2, next: nnNode, previous: nnNode})
const pgbNode = new DoubleNode({data: 3, next: ngNode, previous: nbNode})
const pbNode = new DoubleNode({data: 4, next: ngNode, previous: "node"})
it('returns the correct type, if specified', function() {
expect(pgNode.getPrevious() instanceof DoubleNode).to.be.true
})
it('returns a DoubleNode, if an invalid one is specified', function() {
expect(pgbNode.getPrevious() instanceof DoubleNode).to.be.true
})
it('returns the correct value, if specified', function() {
expect(pgNode.getPrevious()).to.be.deep.equal(nnNode)
})
it(
'returns a DoubleNode with a retrievable property, if specified',
function() {
expect(pgNode.getPrevious().getData()).to.be.equal('astring')
}
)
it('returns null, if unspecified', function() {
expect(nnNode.getPrevious()).to.be.null
})
it('returns null, if specified but not a DoubleNode', function() {
expect(pbNode.getPrevious()).to.be.null
})
it('returns null, if specified but data is unspecified', function() {
expect(dxpbNode.getPrevious()).to.be.null
})
})

context('setPrevious()', function() {
const nnNode = new DoubleNode({data: 0})
const ngNode = new DoubleNode({data: 'astring', next: nnNode})
const nbNode = new DoubleNode({data: 1, next: "nonode"})
const pbNode = new DoubleNode({data: 2, next: ngNode, previous: "bad"})
it('returns a DoubleNode', function() {
expect(nnNode.setPrevious(ngNode) instanceof DoubleNode).to.be.true
})
it('returns the correct DoubleNode', function() {
expect(nnNode.setPrevious(ngNode)).to.be.deep.equal(nnNode)
})
it(
'returns a DoubleNode with a retrievable data property',
function() {
expect(ngNode.setPrevious(nnNode).getData()).to.be.equal('astring')
}
)
it(
'returns a DoubleNode with a retrievable good new previous property',
function() {
expect(nnNode.setPrevious(nnNode).getPrevious())
.to.be.deep.equal(nnNode)
}
)
it(
'returns a DoubleNode with a retrievable bad new next property',
function() {
expect(nnNode.setPrevious(nbNode).getPrevious())
.to.be.deep.equal(nbNode)
}
)
it(
'fails to change previous (from last value), if newPrevious is invalid',
function() {
expect(nnNode.setPrevious("badNode").getPrevious())
.to.be.deep.equal(nbNode)
}
)
})

})
Loading