diff --git a/java_implementation/LinkedList.java b/java_implementation/LinkedList.java new file mode 100644 index 0000000..91140da --- /dev/null +++ b/java_implementation/LinkedList.java @@ -0,0 +1,48 @@ +package datastructures; + +public class LinkedList { + + private Node head; + private int length = 0; + + private class Node { + private final Object data; + private Node next; + + Node(Object data) { + this.data = data; + } + } + + public Object getHeadNode() { + return this.head.data; + } + + public Object getTailNode() { + Node currentNode = this.head; + while (currentNode.next != null) { + currentNode = currentNode.next; + } + return currentNode.data; + } + + public Node insert(Object data) { + Node node = new Node(data); + if (this.head == null) { + this.head = node; + this.length++; + return node; + } + Node currentNode = this.head; + while (currentNode.next != null) { + currentNode = currentNode.next; + } + currentNode.next = node; + this.length++; + return node; + } + + public int size() { + return this.length; + } +} \ No newline at end of file diff --git a/lib/doubly_linked_list.js b/lib/doubly_linked_list.js new file mode 100644 index 0000000..cff667c --- /dev/null +++ b/lib/doubly_linked_list.js @@ -0,0 +1,116 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Node = function Node(data) { + _classCallCheck(this, Node); + + this.data = data; + this.next = null; +}; + +var DoublyLinkedList = function () { + function DoublyLinkedList() { + _classCallCheck(this, DoublyLinkedList); + + this._length = 0; + this.head = null; + this.tail = null; + } + + _createClass(DoublyLinkedList, [{ + key: 'insert', + value: function insert(value) { + var node = new Node(value); + + if (this._length) { + this.tail.next = node; + node.previous = this.tail; + this.tail = node; + } else { + this.head = node; + this.tail = node; + } + this._length++; + return node; + } + }, { + key: 'find', + value: function find(position) { + var currentNode = this.head; + var length = this._length; + var count = 1; + var message = { failure: 'Non-existent node in this list.' }; + + if (length === 0 || position < 1 || position > length) { + throw new Error(message.failure); + } + while (count < position) { + currentNode = currentNode.next; + count++; + } + return currentNode; + } + }, { + key: 'remove', + value: function remove(position) { + var currentNode = this.head; + var count = 1; + var message = { failure: 'non-existent node in this list.' }; + var beforeNodeToDelete = null; + var nodeToDelete = null; + var deletedNode = null; + + if (length === 0 || position < 1 || position > this._length) { + throw new Error(message.failure); + } + + // 2nd use-case: the first node is removed + if (position === 1) { + this.head = currentNode.next; + + // 2nd use-case: there is a second node + if (!this.head) { + this.head.previous = null; + // 2nd use-case: there is no second node + } else { + this.tail = null; + } + + // 3rd use-case: the last node is removed + } else if (position === this._length) { + this.tail = this.tail.previous; + this.tail.next = null; + // 4th use-case: a middle node is removed + } else { + while (count < position) { + currentNode = currentNode.next; + count++; + } + + beforeNodeToDelete = currentNode.previous; + nodeToDelete = currentNode; + afterNodeToDelete = currentNode.next; + + beforeNodeToDelete.next = afterNodeToDelete; + afterNodeToDelete.previous = beforeNodeToDelete; + deletedNode = nodeToDelete; + nodeToDelete = null; + } + + this._length--; + + return message.success; + } + }]); + + return DoublyLinkedList; +}(); + +exports.default = DoublyLinkedList; \ No newline at end of file diff --git a/lib/linked_list.js b/lib/linked_list.js new file mode 100644 index 0000000..0c143cb --- /dev/null +++ b/lib/linked_list.js @@ -0,0 +1,166 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Node = function Node(data) { + _classCallCheck(this, Node); + + this.data = data; + this.next = null; +}; + +var LinkedList = function () { + function LinkedList() { + _classCallCheck(this, LinkedList); + + this.head = null; + this._length = 0; + } + + _createClass(LinkedList, [{ + key: "getHeadNode", + value: function getHeadNode() { + return this.head.data; + } + }, { + key: "getTailNode", + value: function getTailNode() { + var currentNode = this.head; + while (currentNode.next) { + currentNode = currentNode.next; + } + return currentNode.data; + } + }, { + key: "find", + value: function find(position) { + var currentNode = this.head; + var message = { failure: "This node does not exist" }; + var count = 1; + + if (this._length === 0 || position < 1 || position > this._length) { + throw new Error(message.failure); + } + while (count < position) { + currentNode = currentNode.next; + count++; + } + return currentNode; + } + }, { + key: "insert", + value: function insert(data) { + var node = new Node(data); + if (!this.head) { + this.head = node; + this._length += 1; + return node; + } + var currentNode = this.head; + while (currentNode.next !== null) { + currentNode = currentNode.next; + } + currentNode.next = node; + this._length += 1; + return node; + } + }, { + key: "insertBefore", + value: function insertBefore(data, newData) { + var currentNode = this.head; + var insertedNode = void 0; + while (currentNode !== null && insertedNode == undefined) { + if (JSON.stringify(currentNode.next.data) === JSON.stringify(data)) { + insertedNode = new Node(newData); + insertedNode.next = currentNode.next; + currentNode.next = insertedNode; + } + if (currentNode === this.head && currentNode.data === data) { + insertedNode = new Node(newData); + insertedNode.next = currentNode; + this.head = insertedNode; + } + } + this._length += 1; + return insertedNode; + } + }, { + key: "insertAfter", + value: function insertAfter(data, newData) { + var node = new Node(newData); + var currentNode = this.head; + + while (currentNode.next) { + if (currentNode.data === data) { + node.next = currentNode.next; + currentNode.next = node; + return node; + } + currentNode.next = node; + } + } + }, { + key: "removeFirst", + value: function removeFirst() { + var currentNode = this.head; + this.head = currentNode.next; + currentNode = null; + this._length--; + } + }, { + key: "remove", + value: function remove(position) { + var currentNode = this.head; + var count = 0; + var message = { failure: 'Failure: non-existent node in this list.' }; + var beforeNodeToDelete = null; + var nodeToDelete = null; + var deletedNode = null; + + if (position < 0 || position > this._length) { + throw new Error(message.failure); + } + while (count < position) { + beforeNodeToDelete = currentNode; + nodeToDelete = currentNode.next; + count++; + } + beforeNodeToDelete.next = nodeToDelete.next; + deletedNode = nodeToDelete; + nodeToDelete = null; + this._length--; + + return deletedNode; + } + }, { + key: "size", + value: function size() { + return this._length; + } + }, { + key: "isEmpty", + value: function isEmpty() { + if (!this.head) { + return true; + } + return false; + } + }, { + key: "clear", + value: function clear() { + this.head = null; + this._length = 0; + this.data = null; + } + }]); + + return LinkedList; +}(); + +exports.default = LinkedList; \ No newline at end of file diff --git a/lib/node.js b/lib/node.js new file mode 100644 index 0000000..317ab95 --- /dev/null +++ b/lib/node.js @@ -0,0 +1,50 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Node = function () { + function Node() { + _classCallCheck(this, Node); + + this.data = null; + this.next = null; + } + + _createClass(Node, [{ + key: "getData", + value: function getData(data) { + return data; + } + }, { + key: "setNext", + value: function setNext(data) { + var currentNode = new Node(); + currentNode.data = data; + this.next = currentNode; + return this; + } + }, { + key: "getNext", + value: function getNext() { + if (this.next === null) {} + return this.next; + } + }]); + + return Node; +}(); + +// const node = new Node() +// node.data = 15 +// // console.log(node) +// node.setNext(14) +// // console.log(node) +// console.log(node.getNext().data) + +exports.default = Node; \ No newline at end of file diff --git a/lib/stack.js b/lib/stack.js index 9de25fb..3eaa066 100644 --- a/lib/stack.js +++ b/lib/stack.js @@ -1,13 +1,65 @@ -'use strict'; +"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var Stack = function Stack() { - _classCallCheck(this, Stack); -}; +var Stack = function () { + function Stack() { + _classCallCheck(this, Stack); + + this.storage = ""; + this._length = 0; + } + + _createClass(Stack, [{ + key: "push", + value: function push(value) { + this.storage = this.storage.concat("***", value); + this._length++; + } + }, { + key: "pop", + value: function pop() { + var str = this.storage.slice(this.storage.lastIndexOf('***') + 3); + this.storage = this.storage.substring(0, this.storage.lastIndexOf('***')); + this._length--; + return str; + } + }, { + key: "size", + value: function size() { + return this._length; + } + + // peek() { + // return this.storage.charAt(3) + // } + + }, { + key: "isEmpty", + value: function isEmpty() { + if (this._length == 0) { + return true; + } + return false; + } + }, { + key: "length", + value: function length() { + return this._length; + } + }]); + + return Stack; +}(); + +// const stack = new Stack() +// stack.push("RedBeans") +// console.log(stack.length()) exports.default = Stack; \ No newline at end of file diff --git a/package.json b/package.json index d47a351..0dc2097 100644 --- a/package.json +++ b/package.json @@ -3,16 +3,18 @@ "description": "Tests and implementations for common data structures.", "private": false, "version": "0.0.0", + "scripts": { + "build": "babel src -d lib", + "build:watch": "npm run build -- --watch", + "test": "mocha --compilers js:babel-register ./spec/*.js || true" + }, "devDependencies": { "babel-cli": "^6.18.0", + "babel-core": "^6.24.1", "babel-preset-env": "^1.1.4", "babel-register": "^6.18.0", "chai": "~1.8.0", "chai-change": "^2.1.2", "mocha": "2.0.1" - }, - "scripts": { - "build": "babel src -d lib", - "test": "mocha --compilers js:babel-register ./spec/*.js" } } diff --git a/spec/doubly_linked_list.js b/spec/doubly_linked_list.js new file mode 100644 index 0000000..ce76a38 --- /dev/null +++ b/spec/doubly_linked_list.js @@ -0,0 +1,123 @@ +import chai, { expect } from 'chai' +import chaiChange from 'chai-change' +import DoublyLinkedList from '../src/linked_list' + +chai.use(chaiChange) + +let dl + +describe('DoublyLinkedList', () => { + beforeEach('instantiates a new DoublyLinkedList before each test', () => { + dl = new DoublyLinkedList() + }) + + context('insert()', () => { + it('inserts the value to the list', () => { + expect( () => { dl.insert(15) }) + .to.alter(() => dl.size(), { from:0, to: 1}); + }) + + // it('inserts a node to the tail of the list', () => { + // dl.insert(10) + // dl.insert(11) + // dl.insert(12) + // dl.insert(13) + // expect(dl.getTailNode()).to.eql(13) + // }) + }) + + // context('insertBefore()', () => { + + // it('inserts a node with data Sabrin before the first node containing Aileen', + // () => { + // dl.insert('Aileen') + // dl.insert('Sabrin') + // expect( () => { + // dl.insertBefore('Sabrin', 'Jas') + // }) + // .to.alter( () => dl.size(), { from: 2, to: 3}) + // }) + + // it('inserts a node with data Sabrin before the head node containing Aileen', () => { + // dl.insert('Aileen') + // dl.insert('Jas') + // dl.insertBefore('Jas', 'Sabrin') + // expect(dl.getHeadNode()).to.eql('Aileen') + // }) + // }) + + // context('insertAfter()', () => { + // it('inserts a node with data Jacky after the first node containing Aileen', + // () => { + // expect( () => { + // dl.insert('Aileen') + // dl.insertAfter('Aileen', 'Jacky') + // }) + // .to.alter( () => dl.size(), { from: 0, to: 1}) + // }) + // }) + + context('remove(position)', () => { + it('Removes the node from a position in the list', () => { + dl.insert('Sabrin') + dl.insert('James') + dl.insert('Aileen') + dl.remove(2) + + expect( dl.head.next.data ).to.eql('Aileen') + }) + }) + + // context('removeFirst()', () => { + // it('removes the head node from the list', () => { + // dl.insert('JavaScript') + // dl.insert('Java') + // dl.insert('Angular') + // dl.insert('React') + // dl.removeFirst() + + // expect( dl.getHeadNode() ).to.eql('Java') + // }) + // }) + + context('getHeadNode()', () => { + it('returns the first node in the list', () => { + dl.insert('Sabrin') + expect(dl.getHeadNode() ).to.eql('Sabrin'); + }) + }) + + context('size()', () => { + it('returns the size of the list', () => { + dl.insert('Sabrin') + expect( dl.size() ).to.eql( 1 ) + }) + }) + + context('isEmpty()', () => { + it('returns true if the list is empty', () => { + expect(dl.size()).to.eql(0) + }) + + it('returns false if the list contains a node', () => { + expect( () => { + dl.insert(15) + dl.clear() + }) + .to.alter(() => dl.size(), { by: 0}); + }) + }) + + context('find(position)', () => { + it('returns the first node containing the provided data', () => { + dl.insert('Sabrin') + dl.insert('Aileen') + dl.insert('Jas') + dl.insert('Mishi') + + expect(dl.find(3).data).to.eql('Jas') + }) + }) + +}) + diff --git a/spec/linked_list.js b/spec/linked_list.js new file mode 100644 index 0000000..e3e5e4a --- /dev/null +++ b/spec/linked_list.js @@ -0,0 +1,125 @@ +import chai, { expect } from 'chai' +import chaiChange from 'chai-change' +import LinkedList from '../src/linked_list' + +chai.use(chaiChange) + +let ll + +describe('LinkedList', () => { + beforeEach('instantiates a new LinkedList before each test', () => { + ll = new LinkedList() + }) + + context('insert()', () => { + it('inserts the value to the list', () => { + expect( () => { ll.insert(15) }) + .to.alter(() => ll.size(), { from:0, to: 1}); + }) + + it('inserts a node to the tail of the list', () => { + ll.insert(10) + ll.insert(11) + ll.insert(12) + ll.insert(13) + expect(ll.getTailNode()).to.eql(13) + }) + }) + + context('insertBefore()', () => { + + it('inserts a node with data Sabrin before the first node containing Aileen', + () => { + ll.insert('Aileen') + ll.insert('Sabrin') + expect( () => { + ll.insertBefore('Sabrin', 'Jas') + }) + .to.alter( () => ll.size(), { from: 2, to: 3}) + }) + + it('inserts a node with data Sabrin before the head node containing Aileen', () => { + ll.insert('Aileen') + ll.insert('Jas') + ll.insertBefore('Jas', 'Sabrin') + expect(ll.getHeadNode()).to.eql('Aileen') + }) + }) + + + + context('insertAfter()', () => { + it('inserts a node with data Jacky after the first node containing Aileen', + () => { + expect( () => { + ll.insert('Aileen') + ll.insertAfter('Aileen', 'Jacky') + }) + .to.alter( () => ll.size(), { from: 0, to: 1}) + }) + }) + + context('remove(position)', () => { + it('Removes the node from a position in the list', () => { + ll.insert('Sabrin') + ll.insert('James') + ll.insert('Aileen') + ll.remove(2) + + expect( ll.head.next.data ).to.eql('Aileen') + }) + }) + + context('removeFirst()', () => { + it('removes the head node from the list', () => { + ll.insert('JavaScript') + ll.insert('Java') + ll.insert('Angular') + ll.insert('React') + ll.removeFirst() + + expect( ll.getHeadNode() ).to.eql('Java') + }) + }) + + context('getHeadNode()', () => { + it('returns the first node in the list', () => { + ll.insert('Sabrin') + expect(ll.getHeadNode() ).to.eql('Sabrin'); + }) + }) + + context('size()', () => { + it('returns the size of the list', () => { + ll.insert('Sabrin') + expect( ll.size() ).to.eql( 1 ) + }) + }) + + context('isEmpty()', () => { + it('returns true if the list is empty', () => { + expect(ll.size()).to.eql(0) + }) + + it('returns false if the list contains a node', () => { + expect( () => { + ll.insert(15) + ll.clear() + }) + .to.alter(() => ll.size(), { by: 0}); + }) + }) + + context('find(position)', () => { + it('returns the first node containing the provided data', () => { + ll.insert('Sabrin') + ll.insert('Aileen') + ll.insert('Jas') + ll.insert('Mishi') + + expect(ll.find(3).data).to.eql('Jas') + }) + }) + +}) + diff --git a/spec/node.js b/spec/node.js new file mode 100644 index 0000000..f6c9eaa --- /dev/null +++ b/spec/node.js @@ -0,0 +1,33 @@ +import chai, { expect } from 'chai' +import chaiChange from 'chai-change' +import Node from '../src/node' + +chai.use(chaiChange) + +describe('Node', () => { + + it('is a function', () => { + const node = new Node(15) + expect(Node).to.be.a('function') + }) + + it('changes the reference to the next node and returns the original node', () => { + const node = new Node() + node.setNext(14) + expect(node.getNext().data).to.eql(14) + }) + + it('returns the next node', () => { + const node = new Node() + node.setNext('Sabrin') + node.getNext() + expect(node.getNext().data).to.eql('Sabrin') + }) + + it('returns null if no next node', () => { + const node = new Node() + expect(node.getNext()).to.eql(null) + }) + +}) + diff --git a/spec/stack.js b/spec/stack.js index 743122a..ff7399b 100644 --- a/spec/stack.js +++ b/spec/stack.js @@ -4,8 +4,12 @@ import Stack from '../src/stack' chai.use(chaiChange) +let stack + describe('Stack', () => { - 'use strict' + beforeEach('instantiates a new Stack before each test', () => { + stack = new Stack() + }) it('exists', () => { expect(Stack).to.be.a('function') @@ -13,10 +17,21 @@ describe('Stack', () => { context('push()', () => { it('pushes an element to the top of the stack.', () => { - const myStack = new Stack() - expect(() => myStack.push('foo')) - .to.alter(() => myStack.length(), { from: 0, to: 1 }) + expect(() => stack.push('Java')) + .to.alter(() => stack.size(), { from: 0, to: 1 }) }) }) + + context('pop()', () => { + it('returns and removes the top element in the stack', () => { + stack.push('Python') + stack.push('Ruby') + stack.push('Rails') + stack.push('JavaScript') + + expect(stack.pop()).to.eql('JavaScript') + }) + }) + }) diff --git a/src/doubly_linked_list.js b/src/doubly_linked_list.js new file mode 100644 index 0000000..bd6a072 --- /dev/null +++ b/src/doubly_linked_list.js @@ -0,0 +1,114 @@ +class Node { + constructor(data) { + this.data = data + this.next = null + } +} + +class DoublyLinkedList { + constructor() { + this._length = 0 + this.head = null + this.tail = null + } + + getHeadNode() { + return this.head + } + + getTailNode() { + return this.tail + } + + insert(value) { + var node = new Node(value); + + if (this._length) { + this.tail.next = node + node.previous = this.tail + this.tail = node + } else { + this.head = node + this.tail = node + } + this._length++ + return node + } + + find(position) { + let currentNode = this.head + let length = this._length + let count = 1 + let message = {failure: 'Non-existent node in this list.'} + + if (length === 0 || position < 1 || position > length) { + throw new Error(message.failure) + } + while (count < position) { + currentNode = currentNode.next + count++ + } + return currentNode + } + + remove(position) { + let currentNode = this.head + let count = 1 + let message = {failure: 'non-existent node in this list.'} + let beforeNodeToDelete = null + let nodeToDelete = null + let deletedNode = null + + if (length === 0 || position < 1 || position > this._length) { + throw new Error(message.failure) + } + if (!this.head) { + this.head.previous = null + } else { + this.tail = null + } else if (position === this._length) { + this.tail = this.tail.previous; + this.tail.next = null; + } else { + while (count < position) { + currentNode = currentNode.next; + count++; + } + beforeNodeToDelete = currentNode.previous; + nodeToDelete = currentNode; + afterNodeToDelete = currentNode.next; + + beforeNodeToDelete.next = afterNodeToDelete; + afterNodeToDelete.previous = beforeNodeToDelete; + deletedNode = nodeToDelete; + nodeToDelete = null; + } + this._length--; + return message.success; + } + + // removeFirst(position) { + // if (position === 1) { + // this.head = currentNode.next; + // } + + isEmpty() { + if(!this.head) { + return true + } + return false + } + + clear() { + this._length = 0 + this.head = null + this.tail = null + } + + size() { + return this._length + } + +} + +export default DoublyLinkedList diff --git a/src/linked_list.js b/src/linked_list.js new file mode 100644 index 0000000..75c6867 --- /dev/null +++ b/src/linked_list.js @@ -0,0 +1,141 @@ +class Node { + constructor(data) { + this.data = data + this.next = null + } +} + +class LinkedList { + constructor() { + this.head = null + this._length = 0 + } + + getHeadNode() { + return this.head.data + } + + getTailNode() { + let currentNode = this.head + while(currentNode.next) { + currentNode = currentNode.next + } + return currentNode.data + } + + find(position) { + let currentNode = this.head + let message = {failure: "This node does not exist"} + let count = 1 + + if (this._length === 0 || position < 1 || position > this._length) { + throw new Error(message.failure); + } + while (count < position) { + currentNode = currentNode.next; + count++; + } + return currentNode; + } + + insert(data) { + let node = new Node(data) + if(!this.head) { + this.head = node + this._length += 1 + return node + } + let currentNode = this.head + while(currentNode.next !== null) { + currentNode = currentNode.next + } + currentNode.next = node + this._length += 1 + return node + } + + insertBefore(data, newData) { + let currentNode = this.head + let insertedNode + while ( (currentNode !== null) && (insertedNode == undefined) ) { + if(JSON.stringify(currentNode.next.data) === JSON.stringify(data)) { + insertedNode = new Node( newData ) + insertedNode.next = currentNode.next + currentNode.next = insertedNode + } + if( (currentNode === this.head) && (currentNode.data === data) ) { + insertedNode = new Node( newData ) + insertedNode.next = currentNode + this.head = insertedNode + } + } + this._length += 1 + return insertedNode + } + + insertAfter(data, newData) { + let node = new Node( newData ) + let currentNode = this.head + + while( currentNode.next ) { + if( currentNode.data === data ) { + node.next = currentNode.next + currentNode.next = node + return node + } + currentNode.next = node + } + } + + removeFirst() { + let currentNode = this.head + this.head = currentNode.next + currentNode = null + this._length-- + } + + remove(position) { + let currentNode = this.head + let count = 0 + let message = {failure: 'Failure: non-existent node in this list.'} + let beforeNodeToDelete = null + let nodeToDelete = null + let deletedNode = null + + if( position < 0 || position > this._length ) { + throw new Error(message.failure) + + } + while (count < position) { + beforeNodeToDelete = currentNode + nodeToDelete = currentNode.next + count++ + } + beforeNodeToDelete.next = nodeToDelete.next + deletedNode = nodeToDelete + nodeToDelete = null + this._length-- + + return deletedNode + } + + size() { + return this._length + } + + isEmpty() { + if(!this.head) { + return true + } + return false + } + + clear() { + this.head = null + this._length = 0 + this.data = null + } + +} + +export default LinkedList \ No newline at end of file diff --git a/src/node.js b/src/node.js new file mode 100644 index 0000000..7e7e45c --- /dev/null +++ b/src/node.js @@ -0,0 +1,33 @@ +class Node { + constructor() { + this.data = null + this.next = null + } + + getData(data) { + return data + } + + setNext(data) { + const currentNode = new Node() + currentNode.data = data + this.next = currentNode + return this + } + + getNext() { + if (this.next === null) { + } + return this.next + } + +} + +// const node = new Node() +// node.data = 15 +// // console.log(node) +// node.setNext(14) +// // console.log(node) +// console.log(node.getNext().data) + +export default Node \ No newline at end of file diff --git a/src/stack.js b/src/stack.js index dcd1d13..715589a 100644 --- a/src/stack.js +++ b/src/stack.js @@ -1,5 +1,43 @@ -'use strict' +class Stack { + constructor() { + this.storage = "" + this._length = 0 + } -export default class Stack { - // your code here + push(value) { + this.storage = this.storage.concat("***", value) + this._length++ + } + + pop() { + let str = this.storage.slice(this.storage.lastIndexOf('***') + 3) + this.storage = this.storage.substring(0, this.storage.lastIndexOf('***')) + this._length-- + return str + } + + size() { + return this._length + } + + // peek() { + // return this.storage.charAt(3) + // } + + isEmpty() { + if (this._length == 0) { + return true + } + return false + } + + length() { + return this._length + } } + +// const stack = new Stack() +// stack.push("RedBeans") +// console.log(stack.length()) + +export default Stack \ No newline at end of file