From 5859323508cb04d0bcf134063ca7bd3efde48224 Mon Sep 17 00:00:00 2001 From: je-lopez Date: Tue, 13 Mar 2018 20:42:03 -0700 Subject: [PATCH 1/3] creates node class and tests --- spec/node.js | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/node.js | 21 +++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 spec/node.js create mode 100644 src/node.js diff --git a/spec/node.js b/spec/node.js new file mode 100644 index 0000000..f1a25e6 --- /dev/null +++ b/spec/node.js @@ -0,0 +1,48 @@ +import chai, { expect } from 'chai' +import chaiChange from 'chai-change' +import Node from '../src/node' + +chai.use(chaiChange) + +describe.only('Node', () => { + 'use strict' + + it('exists', () => { + expect(Node).to.be.a('function') + }) + + context('getData()', function() { + it('returns the node\'s data', function() { + const myNode = new Node({data: 'hello'}) + + expect(myNode.getData()).to.equal('hello') + }) + }) + + context('getNext()', function() { + it('returns null if next node is not set', function() { + const myNode = new Node({data: 'hello'}) + + expect(myNode.getNext()) + .to.equal(null) + }) + + it('returns next node if set', function() { + const aNode = new Node({data: 'world'}) + const myNode = new Node({data: 'hello', next: aNode }) + + expect(myNode.getNext()) + .to.equal(aNode) + }) + }) + + context('setNext()', function() { + it('sets next node', function() { + const myNode = new Node({data: 'hello'}) + const newNode = new Node({data: 'world'}) + + expect(() => myNode.setNext(newNode)) + .to.alter(() => myNode.getNext(), { from: null, to: newNode }) + }) + }) +}) diff --git a/src/node.js b/src/node.js new file mode 100644 index 0000000..f9ab0ec --- /dev/null +++ b/src/node.js @@ -0,0 +1,21 @@ +'use strict' + +export default class Node { + constructor({ data, next }) { + this.data = data; + this.next = next || null; + } + + getData() { + return this.data; + } + + getNext() { + return this.next; + } + + setNext(nextNode) { + this.next = nextNode; + return this; + } +} From b7ad844dd805970cd96840049e9eee00c7db6c7a Mon Sep 17 00:00:00 2001 From: je-lopez Date: Wed, 14 Mar 2018 20:19:19 -0700 Subject: [PATCH 2/3] removes .only from tests --- spec/node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/node.js b/spec/node.js index f1a25e6..6fa1faf 100644 --- a/spec/node.js +++ b/spec/node.js @@ -4,7 +4,7 @@ import Node from '../src/node' chai.use(chaiChange) -describe.only('Node', () => { +describe('Node', () => { 'use strict' it('exists', () => { From 711e3843b973effb3976c68bf8f4d864890bbc33 Mon Sep 17 00:00:00 2001 From: je-lopez Date: Wed, 14 Mar 2018 21:11:23 -0700 Subject: [PATCH 3/3] creates linked list class and tests --- spec/linkedList.js | 33 ++++++++++ src/linkedList.js | 154 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 spec/linkedList.js create mode 100644 src/linkedList.js diff --git a/spec/linkedList.js b/spec/linkedList.js new file mode 100644 index 0000000..1c732d7 --- /dev/null +++ b/spec/linkedList.js @@ -0,0 +1,33 @@ +import chai, { expect } from 'chai' +import chaiChange from 'chai-change' +// import Node from '../src/node' +import LinkedList from '../src/linkedList' + +chai.use(chaiChange) + +describe('LinkedList', function() { + 'use strict' + + it('exists', function() { + expect(LinkedList).to.be.a('function') + }) + + context('getHeadNode()', function() { + it('returns null when there is no head node', function() { + const myLinkedList = new LinkedList() + expect(myLinkedList.getHeadNode()).to.equal(null) + }) + + it('returns the head node', function() { + const myLinkedList = new LinkedList() + myLinkedList.insertFirst('hello') + + expect(myLinkedList.getHeadNode().getData()).to.equal('hello') + }) + }) + + +}) + + // expect(() => myLinkedList.push('foo')) + // .to.alter(() => myLinkedList.length(), { from: 0, to: 1 }) \ No newline at end of file diff --git a/src/linkedList.js b/src/linkedList.js new file mode 100644 index 0000000..da4031f --- /dev/null +++ b/src/linkedList.js @@ -0,0 +1,154 @@ +'use strict' + +import Node from './node'; + +export default class linkedList { + constructor() { + this.headNode = null; + this.tailNode = null; + this.size = 0; + } + + getHeadNode() { + return this.headNode; + } + + getTailNode() { + return this.tailNode; + } + + contains(data) { + let node = this.headNode; + + while(true) { + if (node.getData() === data) { + return true; + } + + if (node === this.tailNode) { + return false; + } + + node = node.getNext(); + } + } + + find(data) { + let node = this.headNode; + + while(true) { + if (node.getData() === data) { + return node; + } + + if (node === this.tailNode) { + return -1; + } + + node = node.getNext(); + } + } + + insert(data) { + const node = new Node({ data }); + + if (this.tailNode) { + this.tailNode.setNext(node); + } + + this.tailNode = node; + this.size++; + } + + insertFirst(data) { + const node = new Node({ data }); + + if (this.headNode) { + node.setNext(this.headNode); + } + + this.headNode = node; + this.size++; + } + + insertBefore(reference, data) { + const node = new Node({ data }); + let currentNode = this.headNode.getNext(); + let previousNode = this.headNode; + let inserted = false; + + if (this.headNode.getData() === reference) { + node.setNext(this.headNode); + this.headNode = node; + } + + while(!inserted) { + if (!currentNode) { + return -1; + } + + if (currentNode.getData() === reference) { + previousNode.setNext(node); + node.setNext(currentNode); + inserted = true; + } + + previousNode = currentNode; + currentNode = currentNode.getNext(); + } + + this.size++; + } + + insertAfter(reference, data) { + const node = new Node({ data }); + let currentNode = this.headNode; + let nextNode = currentNode.getNext(); + let inserted = false; + + while(!inserted) { + if (currentNode.getData() === reference) { + currentNode.setNext(node); + node.setNext(nextNode); + inserted = true; + } + + if (!nextNode) { + return -1; + } + + currentNode = nextNode; + nextNode = nextNode.getNext(); + } + } + + remove() { + let node = this.headNode; + + while(node.getNext() !== this.tailNode) { + node = node.getNext(); + } + + node.setNext(null); + this.tailNode = node; + } + + removeFirst() { + const newHead = this.headNode.getNext(); + this.headNode = newHead; + } + + isEmpty() { + return this.size === 0; + } + + size() { + return this.size; + } + + clear() { + this.headNode = null; + this.tailNode = null; + this.size = 0; + } +}