Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules/
.DS_Store
34 changes: 32 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,41 @@

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 for the [Core Data Structures](Core Data Structures--Basic) goal.

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.

## Usage and Examples

Expand Down
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
43 changes: 43 additions & 0 deletions spec/nodeTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

import chai, { expect } from 'chai'
import chaiChange from 'chai-change'
import Node from '../src/node'

chai.use(chaiChange)

describe('Node', () => {
'use strict'
const nodeA = new Node( {data: 'apple'} )
const nodeB = new Node( {data: 'banana'} )

it('is a function', () => {
expect(Node).to.be.a('function')
})

context('getData()', () => {
it('gets the data from the node.', () => {
expect( nodeA.getData() ).to.equal('apple')
})
})

context('setNext()', () => {
it('points the reference to the next node.', () => {
expect( () => nodeA.setNext(nodeB) ).to.alter( () => nodeA.data.next, { from: undefined, to: nodeB } )
})

it('returns the original.', () => {
expect( nodeA.setNext(nodeB) ).to.equal(nodeA)
})
})

context('getNext()', () => {
it('returns the next node', () => {
nodeA.setNext(nodeB)
expect( nodeA.getNext() ).to.equal(nodeB)
})

it('returns null if no next node.', () => {
expect( nodeB.getNext() ).to.equal(null)
})
})
})
36 changes: 36 additions & 0 deletions spec/priority_node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import chai, { expect } from 'chai'
import chaiChange from 'chai-change'
import PriorityNode from '../src/priority_node'

chai.use(chaiChange)

describe('PriorityNode', () => {
'use strict'

it('is a function', () => {
expect(PriorityNode).to.be.a('function')
})

context('getData()', () => {
it('returns the correct type, if string', () => {
const levelZero = new PriorityNode({data: "level0", priority: 0})
const data = levelZero.getData()
expect(data).to.be.a('string')
})
it('returns the correct value, if a string', () => {
const levelZero = new PriorityNode({data: "level0", priority: 0})
const data = levelZero.getData()
expect(data).to.be.equal('level0')
})
it('returns the correct type, if number', () => {
const levelZero = new PriorityNode({data: 0, priority: 0})
const data = levelZero.getData()
expect(data).to.be.a('number')
})
it('returns the correct value, if a number', () => {
const levelZero = new PriorityNode({data: 0, priority: 0})
const data = levelZero.getData()
expect(data).to.be.equal(0)
})
})
})
File renamed without changes.
28 changes: 28 additions & 0 deletions src/node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict'

// A very basic data structure that can contain some value and a reference to another node.
export default class Node {
constructor(data) {
this.data = data
this.next = undefined
}

// returns the data ("apple") of the node
getData() {
return this.data.data
}

// changes the reference to the next node and returns the original node
setNext(element) {
this.data.next = element
return this
}

// returns the next node, or null if no next node
getNext() {
if (this.data.next) {
return this.data.next
}
return null
}
}
36 changes: 36 additions & 0 deletions src/priority_node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use strict'

/*
Class declaration for PriorityNode and export statement making that
object the default export from this module.
*/
export default class PriorityNode {
constructor(nodeProps) {
this.data = nodeProps.data;
this.priority = nodeProps.priorty;
this.next = nodeProps.next;
}
// Returns the node’s data.
getData() {
return this.data;
}
// Returns the node’s priority.
getPriority() {
return this.priority;
}
// Returns the next node, or null if none.
getNext() {
return this.next || null;
}
// Changes the node’s priority and returns the post-change node.
setPriority(newPriority) {
this.priority = newPriority;
return this;
}
// Changes the next node and returns the pre-change node.
setNext(newNext) {
const origThis = this;
this.next = newNext;
return origThis;
}
}
File renamed without changes.