pporche87 / core-data-structures

Tests and implementations for common data structures.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Advanced Data Structures

TEAM: Patrick Porche

TEAM NAME: drab-egret

Tests and implementations for advanced data structures. See the full list in the data-structures.md file.

Base repository for the Advanced Data Structures goal.

Installation and Setup

For this project, we created both tests and implementations of core data structures. Begin with installing your dependencies from the package.json file.

Check for mocha and chai in your .json file. If not already provided, use the link below to install.

Use npm install in order to install all dependencies.

Usage and Examples

This is the treeNode function in my treeNode.js file, it helps implement a standard binary search tree acting as nodes on a new linked list.

export default class TreeNode {
	constructor(data, left, right) {
		this.data = data
		this.left = null
		this.right = null
	}

	getData() {
		return this.data
	}

	getLeft() {
		return this.left
	}

	setLeft(leftReference) {
		this.left = leftReference
		return this.data
	}

	getRight() {
		return this.right
	}

	setRight(rightReference) {
		this.right = rightReference
		return this.data
	}
}

This is the treeNode test function in my treeNode_Test.js file, it checks to see if the data returned matches the data expected from common treeNode functions.

import chai, { expect } from 'chai'
import chaiChange from 'chai-change'
import TreeNode from '../../src/advanced/TreeNode'

chai.use(chaiChange)

describe('TreeNode', () => {

	it('exists', () => {
		expect(TreeNode).to.be.a('function')
	})

	context('getData()', () => {
		it('returns the nodes data', () => {
			const leastNode = new TreeNode({data: 3})

			expect(leastNode.getData() ).to.deep.equal({data: 3})
		})
	})

	context('getLeft()', () => {
		it('returns the left node or null if none', () => {
			const leastNode = new TreeNode({data: 3})
			const moreNode = new TreeNode({data: 10})

			moreNode.setLeft(leastNode)
			expect(moreNode.getLeft() ).to.equal(leastNode)
			expect(moreNode.getRight() ).to.equal(null)
		})
	})

	context('setleft(leftReference)', () => {
		it('changes the reference to the left node and returns the original node', () => {
			const leastNode = new TreeNode({data: 3})
			const moreNode = new TreeNode({data: 10})
			const midNode = new TreeNode({data: 7, left: leastNode, right: moreNode})

			midNode.setLeft(leastNode)
			expect(midNode.left).to.equal(leastNode)
		})
	})

	context('getRight()', () => {
		it('returns the right node or null if none', () => {
			const leastNode = new TreeNode({data: 3})
			const moreNode = new TreeNode({data: 10})

			moreNode.setRight(leastNode)
			expect(moreNode.getRight() ).to.equal(leastNode)
			expect(moreNode.getLeft() ).to.equal(null)
		})
	})

	context('setRight(rightReference)', () => {
		it('changes the reference to the right node and returns the original node', () => {
			const leastNode = new TreeNode({data: 3})
			const moreNode = new TreeNode({data: 10})
			const midNode = new TreeNode({data: 7, left: leastNode, right: moreNode})

			midNode.setRight(moreNode)
			expect(midNode.right).to.equal(moreNode)
		})
	})

})

Specifications

  • Artifact produced is a fork of the [core-data-structures][core-data-structures] repo.
  • Can run all tests with npm test.
  • All tests are passing.
  • Unit tests exist for all methods of Hash Table.
  • A working implementation of the Binary (Search) Tree data structure is complete.
  • Unit tests exist for all methods of Binary (Search) Tree.
  • A working implementation of the Tree Node data structure is complete.
  • Unit tests exist for all methods of Tree Node.
  • A working implementation of the Directed Graph data structure is complete.
  • Unit tests exist for all methods of Directed Graph.
  • Repository includes a README file with basic installation and setup instructions.
  • All dependencies are properly declared in package.json.
  • All major features are added via pull requests with a clear description and concise commit messages.
  • Code uses a linter and there are no linting errors.
  • Variables, functions, files, etc. have appropriate and meaningful names.
  • Functions are small and serve a single purpose.
  • The artifact produced is properly licensed, preferably with the [MIT license][mit-license].

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 [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

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.

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

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

Tree Node

To implement a standard binary search tree, use a tree node data structure in your implementation. You don't need to write tests for this object or expose its interface in the public API. Use this interface as a reference:

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

- [x] midNode.getData()           // returns the node's data
- [x] midNode.getLeft()           // returns the left node or null if none
- [x] midNode.setLeft(leastNode)  // changes the reference to the left node and returns the original node
- [x] midNode.getRight()          // returns the right node or null if none
- [x] 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 [edited]:

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

const diGraph = new DirectedGraph()
- [x] diGraph.addVertex('v1')               // adds a vertex to the graph.
- [x] diGraph.hasVertex('v1')               // returns true if the graph contains the vertex or false if not.
- [x] diGraph.addDirection('v1', 'v2')      // adds a direction from 'v1' to 'v2'.
- [x] diGraph.hasDirection('v1', 'v2')      // returns true if there's a direction from 'v1' to 'v2'.
- [x] 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.
- [x] diGraph.findPaths('v1', 'v2')         // returns an array of all the paths between two vertices.
- [x] diGraph.removeDirection('v1', 'v2')   // removes an existing direction between 'v1' and 'v2'.
- [x] diGraph.getSeparatedVertices()        // returns an array of all the vertices that are unconnected to the graph (have no direction linking them to another vertex).
- [x] diGraph.removeVertex('v1')            // removes an existing vertex and all its directions (the incoming and outgoing).
- [x] diGraph.count()                       // returns the number of vertices in the graph.

Sources

Most of the above was shamelessly borrowed from Wikipedia and these libraries:

About

Tests and implementations for common data structures.

License:MIT License


Languages

Language:JavaScript 100.0%