From e75588232a1ca7ccadb71ec0b8c369ee5eb5dd2d Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Tue, 12 Dec 2017 14:12:01 -0800 Subject: [PATCH 01/44] finished adding autocmplete, left over from last week --- src/trie.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/trie.py b/src/trie.py index 15d3d70..3797a43 100644 --- a/src/trie.py +++ b/src/trie.py @@ -64,3 +64,59 @@ def remove(self, word): if current.parent: current = current.parent self.tree_size -= 1 + + def trie_traversal(self, start=None): + """Depth-first traveral of Trie.""" + self.visited = [] + + if start: + curr = self.root + for char in start: + if char in curr.children: + curr = curr.children[char] + return 'Invalid starting string.' + return self._combo_gen(curr) + else: + return self._combo_gen(self.root) + + def _combo_gen(self, start): + """.""" + for child, child_node in start.children.items(): + self.visited.append(child) + for node in child_node.children: + self.visited.append(child_node.children[node].letter) + if child_node.children[node].end and not child_node.children: + continue + child_node.children = child_node.children[node].children + for let in self.visited: + yield let + + def _trie_gen(self, start): + """Generator for traversal function.""" + for child in start.children: + return self._recursive_depth(start.children[child]) + + def _recursive_depth(self, node): + """Recursive helper fn for generator.""" + self.visited.append(node.letter) + for child in node.children: + if child.end: + break + yield self._recursive_depth(node.children[child]) + + def autocomplete(self, start): + """Autocomplete using Trie Tree.""" + curr = self.root + for letter in start: + if letter not in curr.children: + return [] + curr = curr.children[letter] + return self._auto_helper(curr, start) + + def _auto_helper(self, node, start): + """Helper fn for autocomplete.""" + if node.end: + yield start + for letter in node.children: + for word in self._auto_helper(node.children[letter], start + letter): + yield word From c1a9d6585dcfe304082b8918edf0404e9d0627ad Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Tue, 12 Dec 2017 14:18:35 -0800 Subject: [PATCH 02/44] adding two new tests to autocmplete in trie. --- src/test_trie.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test_trie.py b/src/test_trie.py index 6b7fbd5..7525fa1 100644 --- a/src/test_trie.py +++ b/src/test_trie.py @@ -163,3 +163,20 @@ def test_size_decreases_with_removing_node(filled_2): assert filled_2.size() == 4 filled_2.remove('az') assert filled_2.size() == 3 + + +def test_trie_autocomplete_on_filled_tree_letter_h(filled_1): + """Autocomplete tests on filled tree.""" + a = filled_1.autocomplete('h') + assert next(a) == 'hello' + assert next(a) == 'helsinki' + assert next(a) == 'heckingoodboye' + + +def test_trie_autocomplete_on_filled_tree_letter_g(filled_1): + """Autocomplete tests on filled tree.""" + a = filled_1.autocomplete('good') + assert next(a) == 'goodbye' + assert next(a) == 'goodlord' + + From ceba63cb1e33d746564d4416b3f5c383067a4103 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Tue, 12 Dec 2017 14:20:12 -0800 Subject: [PATCH 03/44] one more test --- src/test_trie.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test_trie.py b/src/test_trie.py index 7525fa1..ba5b9b0 100644 --- a/src/test_trie.py +++ b/src/test_trie.py @@ -180,3 +180,7 @@ def test_trie_autocomplete_on_filled_tree_letter_g(filled_1): assert next(a) == 'goodlord' +def test_trie_autocomplete_where_no_suggestions(filled_1): + """Autocomplete with a letter not in Trie tree, makes empty list.""" + a = filled_1.autocomplete('z') + assert a == [] From 6ebce109b8d290198f79fa059f46e09f2da4b7b7 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Tue, 12 Dec 2017 14:21:33 -0800 Subject: [PATCH 04/44] assert StopIteration when done. --- src/test_trie.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test_trie.py b/src/test_trie.py index ba5b9b0..327df4c 100644 --- a/src/test_trie.py +++ b/src/test_trie.py @@ -171,6 +171,8 @@ def test_trie_autocomplete_on_filled_tree_letter_h(filled_1): assert next(a) == 'hello' assert next(a) == 'helsinki' assert next(a) == 'heckingoodboye' + with pytest.raises(StopIteration): + assert next(a) def test_trie_autocomplete_on_filled_tree_letter_g(filled_1): @@ -184,3 +186,9 @@ def test_trie_autocomplete_where_no_suggestions(filled_1): """Autocomplete with a letter not in Trie tree, makes empty list.""" a = filled_1.autocomplete('z') assert a == [] + + +# def test_trie_autocomplete_where_no_suggestions(filled_1): +# """Autocomplete with a letter not in Trie tree, makes empty list.""" +# a = filled_1.autocomplete('z') +# assert a == [] From 9cae6edccba56167ede520b777d3fcf5a033fd59 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Tue, 12 Dec 2017 14:23:15 -0800 Subject: [PATCH 05/44] adding error handling for non string input. --- src/test_trie.py | 9 +++++---- src/trie.py | 14 ++++++++------ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/test_trie.py b/src/test_trie.py index 327df4c..d034a63 100644 --- a/src/test_trie.py +++ b/src/test_trie.py @@ -188,7 +188,8 @@ def test_trie_autocomplete_where_no_suggestions(filled_1): assert a == [] -# def test_trie_autocomplete_where_no_suggestions(filled_1): -# """Autocomplete with a letter not in Trie tree, makes empty list.""" -# a = filled_1.autocomplete('z') -# assert a == [] +def test_trie_auto_with_non_string(filled_1): + """Autocomplete with a non string.""" + with pytest.raises(TypeError): + a = filled_1.autocomplete('z') + assert next(a) diff --git a/src/trie.py b/src/trie.py index 3797a43..94e2a6f 100644 --- a/src/trie.py +++ b/src/trie.py @@ -106,12 +106,14 @@ def _recursive_depth(self, node): def autocomplete(self, start): """Autocomplete using Trie Tree.""" - curr = self.root - for letter in start: - if letter not in curr.children: - return [] - curr = curr.children[letter] - return self._auto_helper(curr, start) + if isinstance(start, str): + curr = self.root + for letter in start: + if letter not in curr.children: + return [] + curr = curr.children[letter] + return self._auto_helper(curr, start) + raise TypeError('Autocomplete takes only strings.') def _auto_helper(self, node, start): """Helper fn for autocomplete.""" From 27d365c0e381ef36336562ebb81e693a9ff91b2f Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Tue, 12 Dec 2017 19:58:16 -0800 Subject: [PATCH 06/44] last insertion sort stuff. --- src/insertion-sort.py | 11 +++++++++++ src/test_insertion-sort.py | 1 + 2 files changed, 12 insertions(+) create mode 100644 src/insertion-sort.py create mode 100644 src/test_insertion-sort.py diff --git a/src/insertion-sort.py b/src/insertion-sort.py new file mode 100644 index 0000000..129e52f --- /dev/null +++ b/src/insertion-sort.py @@ -0,0 +1,11 @@ +"""Insertion sort algorithm.""" + + +def insertion_sort(lst): + """Implementation of insertion sort in python.""" + if isinstance(lst, list): + if + for i in lst[1:]: + while lst[i] < lst[i - 1]: + lst[i], lst[i - 1] = lst[i - 1], lst[i] + i -= 1 diff --git a/src/test_insertion-sort.py b/src/test_insertion-sort.py new file mode 100644 index 0000000..d688df6 --- /dev/null +++ b/src/test_insertion-sort.py @@ -0,0 +1 @@ +"""Testing module for insertion sort algorithm.""" \ No newline at end of file From 7658d49726deec931f4b848fb966aa6581244aaf Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 10:07:22 -0800 Subject: [PATCH 07/44] finished insertion sort. --- src/insertion-sort.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/insertion-sort.py b/src/insertion-sort.py index 129e52f..ca4ca9a 100644 --- a/src/insertion-sort.py +++ b/src/insertion-sort.py @@ -4,8 +4,13 @@ def insertion_sort(lst): """Implementation of insertion sort in python.""" if isinstance(lst, list): - if - for i in lst[1:]: - while lst[i] < lst[i - 1]: + for i in range(1, len(lst)): + curr = lst[i] + if not isinstance(i, int): + raise TypeError('Only integers can be in the list.') + while i > 0 and lst[i] < lst[i - 1]: lst[i], lst[i - 1] = lst[i - 1], lst[i] i -= 1 + i = curr + return lst + raise TypeError('Only lists can be used with Insertion Sort.') From 917a87ae924fec68fd776cefc481a38416586d57 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 10:08:37 -0800 Subject: [PATCH 08/44] renaming insertion sort files to use underscore. --- src/{insertion-sort.py => insertion_sort.py} | 0 src/test_insertion-sort.py | 1 - src/test_insertion_sort.py | 2 ++ 3 files changed, 2 insertions(+), 1 deletion(-) rename src/{insertion-sort.py => insertion_sort.py} (100%) delete mode 100644 src/test_insertion-sort.py create mode 100644 src/test_insertion_sort.py diff --git a/src/insertion-sort.py b/src/insertion_sort.py similarity index 100% rename from src/insertion-sort.py rename to src/insertion_sort.py diff --git a/src/test_insertion-sort.py b/src/test_insertion-sort.py deleted file mode 100644 index d688df6..0000000 --- a/src/test_insertion-sort.py +++ /dev/null @@ -1 +0,0 @@ -"""Testing module for insertion sort algorithm.""" \ No newline at end of file diff --git a/src/test_insertion_sort.py b/src/test_insertion_sort.py new file mode 100644 index 0000000..d16dfb8 --- /dev/null +++ b/src/test_insertion_sort.py @@ -0,0 +1,2 @@ +"""Testing module for insertion sort algorithm.""" + From aa86758b71983d1b934aa8f82b180249146cfbad Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 10:17:12 -0800 Subject: [PATCH 09/44] adding first tests for insertion sort. --- src/test_insertion_sort.py | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/test_insertion_sort.py b/src/test_insertion_sort.py index d16dfb8..2ce854c 100644 --- a/src/test_insertion_sort.py +++ b/src/test_insertion_sort.py @@ -1,2 +1,47 @@ """Testing module for insertion sort algorithm.""" +import pytest +from insertion_sort import insertion_sort +from random import randint + + + +def test_ins_sort_on_empty_lst(): + """Sort on empty list as input.""" + assert insertion_sort([]) == [] + + +def test_ins_sort_on_lst_len_1(): + """Test on a list with one thing in it.""" + assert insertion_sort([1]) == [1] + + +def test_ins_sort_on_lst_len_2(): + """Test ins sort on a list with two unordered nums.""" + assert insertion_sort([53, 2]) == [2, 53] + + +def test_ins_sort_on_dictionary(): + """Test ins sort with input of dictionary.""" + with pytest.raises(TypeError): + assert insertion_sort({'1': 1, '2': 2}) + + +def test_ins_sort_on_string(): + """Test insertion doesnt work with string input.""" + with pytest.raises(TypeError): + assert insertion_sort("this wont work") + + +def test_list_with_non_num_inside(): + """Test on a list with a string as one of the items.""" + with pytest.raises(TypeError): + assert insertion_sort([1, 2, 3, 4, 'five', 6, 7]) + + +def test_list_on_randomized_lists(): + """Test using randomly generated lists.""" + for i in range(60): + lst = [randint(0, 1000) for i in range(30)] + sorted_lst = lst.sort() + assert insertion_sort(lst) == sorted_lst From 3ff4b282cdab5df442e9789b67b86b3db8554c80 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 10:17:45 -0800 Subject: [PATCH 10/44] changing test paramerization. --- src/test_insertion_sort.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_insertion_sort.py b/src/test_insertion_sort.py index 2ce854c..79e7172 100644 --- a/src/test_insertion_sort.py +++ b/src/test_insertion_sort.py @@ -43,5 +43,5 @@ def test_list_on_randomized_lists(): """Test using randomly generated lists.""" for i in range(60): lst = [randint(0, 1000) for i in range(30)] - sorted_lst = lst.sort() + sorted_lst = sorted(lst) assert insertion_sort(lst) == sorted_lst From 5364b435fd76f91a3bf4001a860ba51bae479949 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 10:18:32 -0800 Subject: [PATCH 11/44] adding last test for randomized long lsts. --- src/test_insertion_sort.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test_insertion_sort.py b/src/test_insertion_sort.py index 79e7172..c8f0764 100644 --- a/src/test_insertion_sort.py +++ b/src/test_insertion_sort.py @@ -45,3 +45,11 @@ def test_list_on_randomized_lists(): lst = [randint(0, 1000) for i in range(30)] sorted_lst = sorted(lst) assert insertion_sort(lst) == sorted_lst + + +def test_list_on_randomized_long_lists(): + """Test using randomly generated lists.""" + for i in range(15): + long_lst = [randint(0, 1000) for i in range(100)] + sorted_long_lst = sorted(long_lst) + assert insertion_sort(long_lst) == sorted_long_lst From 40f09c3f9c81c40316a8b138710f722d7bf1f9bf Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 10:19:31 -0800 Subject: [PATCH 12/44] adding test to check for negative numbers. --- src/test_insertion_sort.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test_insertion_sort.py b/src/test_insertion_sort.py index c8f0764..a31294b 100644 --- a/src/test_insertion_sort.py +++ b/src/test_insertion_sort.py @@ -39,6 +39,11 @@ def test_list_with_non_num_inside(): assert insertion_sort([1, 2, 3, 4, 'five', 6, 7]) +def test_list_with_negatives(): + """Test on list with neg numbers.""" + assert insertion_sort([-32, 23, 1, 0, 900, -14]) == [-32, -14, 0, 1, 23, 900] + + def test_list_on_randomized_lists(): """Test using randomly generated lists.""" for i in range(60): From 1f4050552cd64cc0aa91376e18d3f9c53b65362e Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 10:22:02 -0800 Subject: [PATCH 13/44] adding to README. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 90a6e94..eb975a8 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,10 @@ **Testing Tools**: pytest, pytest-cov +## Sorting Algorithms: + +* **Insertion Sort** - *The insertion sort algorithm sorts a list of numbers by looping through each individual number in the list one by one, and (if they are smaller than the last index) swapping the two numbers. Unlike bubble sort, after this swap the sort continues to swap the number down into lower indexed positions until it finds the right position. The runtime for this function is at worst-case O(n^2), because in that scenario the list would be exactly the reverse of what it should be.* + ## Data Structures: * **Binary Search Tree** — *a BST is a "tree shaped" data structure containing nodes. Each node can have a maximum of two children or "leaves," and all node values are properly located based on its parents and siblings values. Nodes to the left of the "root"/head node have values smaller than the root. Those to the right have values larger than the root. There are no duplicate values.* From 591ff2e64e265f778ee1f3a6863176070dbffa15 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 10:25:37 -0800 Subject: [PATCH 14/44] adding timeit and if name is main to insertion sort. --- src/insertion_sort.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/insertion_sort.py b/src/insertion_sort.py index ca4ca9a..22cb88c 100644 --- a/src/insertion_sort.py +++ b/src/insertion_sort.py @@ -14,3 +14,32 @@ def insertion_sort(lst): i = curr return lst raise TypeError('Only lists can be used with Insertion Sort.') + +if __name__ == '__main__': # pragama: no cover + import timeit as ti + import random + best_case = [1, 2, 3, 4, 5] + worst_case = [5, 4, 3, 2, 1] + random = [random.randint(1, 100) for i in range(10)] + + time_1 = ti.timeit("insertion_sort(best_case)", + setup="from __main__ import best_case, insertion_sort") + time_2 = ti.timeit("insertion_sort(worst_case)", + setup="from __main__ import worst_case, insertion_sort") + time_3 = ti.timeit("insertion_sort(random)", + setup="from __main__ import random, insertion_sort") + print(""" +Insertion sort compares the vals of an index versus the index - 1, and +(if index is smaller) switches. Them it continues switching until index is +bigger than index - 1. + +Input:[1, 2, 3, 4, 5] +Sort time: {} + +Input:[5, 4, 3, 2, 1] +Sort time: {} + +Input:list(range(5, 0, -1)) +Sort time: {} + """.format(time_1, time_2, time_3)) + From 63d10db370117f65276d79282100cebf95aef7f8 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 15:58:12 -0800 Subject: [PATCH 15/44] creating files for LL and DLL in js-src file --- js-src/js-doubly-linked-list.js | 13 +++++++++++++ js-src/js-linked-list.js | 12 ++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 js-src/js-doubly-linked-list.js create mode 100644 js-src/js-linked-list.js diff --git a/js-src/js-doubly-linked-list.js b/js-src/js-doubly-linked-list.js new file mode 100644 index 0000000..174f6de --- /dev/null +++ b/js-src/js-doubly-linked-list.js @@ -0,0 +1,13 @@ +"use strict"; + +class Node { + constructor(data, nextNode=None, prevNode=None) { + this.data = data + this.nextNode = nextNode + this.prevNode = prevNode + } +} + +class DLL { + +} \ No newline at end of file diff --git a/js-src/js-linked-list.js b/js-src/js-linked-list.js new file mode 100644 index 0000000..bf25898 --- /dev/null +++ b/js-src/js-linked-list.js @@ -0,0 +1,12 @@ +"use strict"; + +class Node { + constructor(data, nextNode=None) { + this.data = data + this.nextNode = nextNode + } +} + +class LL { + +} \ No newline at end of file From f406f80c065aa638fe651e1ff81e2c0208b24cd6 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 16:03:29 -0800 Subject: [PATCH 16/44] adding constructor to LL. --- js-src/js-linked-list.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/js-src/js-linked-list.js b/js-src/js-linked-list.js index bf25898..c2c300b 100644 --- a/js-src/js-linked-list.js +++ b/js-src/js-linked-list.js @@ -1,12 +1,21 @@ "use strict"; class Node { - constructor(data, nextNode=None) { - this.data = data - this.nextNode = nextNode + constructor(data, nextNode=null) { + this.data = data; + this.nextNode = nextNode; } } class LL { - + constructor(iter=null) { + this.head = null; + this.counter = 0; + if (Array.isArray(iter)) { + iterable.forEach(item => this.push(item)); + } + else if (iter != null) { + throw 'LinkedList only takes arrays as inputs.'; + } + } } \ No newline at end of file From 7145bdc0015604d689a8784cf58adea5bfba2d46 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 16:05:35 -0800 Subject: [PATCH 17/44] added semi colon bois --- js-src/js-doubly-linked-list.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/js-src/js-doubly-linked-list.js b/js-src/js-doubly-linked-list.js index 174f6de..fe9667d 100644 --- a/js-src/js-doubly-linked-list.js +++ b/js-src/js-doubly-linked-list.js @@ -2,12 +2,21 @@ class Node { constructor(data, nextNode=None, prevNode=None) { - this.data = data - this.nextNode = nextNode - this.prevNode = prevNode + this.data = data; + this.nextNode = nextNode; + this.prevNode = prevNode; } } class DLL { - + constructor(iter=null) { + this.head = null; + this.tail = null; + if (Array.isArray(iter)) { + iterable.forEach(item => this.push(item)); + } + else if (iter != null) { + throw 'LinkedList only takes arrays as inputs.'; + } + } } \ No newline at end of file From 94ac35eb61a232ba73e90c562e6247a8c41edefc Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 16:21:56 -0800 Subject: [PATCH 18/44] adding more curlybois and adding push and pop fns. --- js-src/js-doubly-linked-list.js | 10 +++++++++- js-src/js-linked-list.js | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/js-src/js-doubly-linked-list.js b/js-src/js-doubly-linked-list.js index fe9667d..6e5ecb9 100644 --- a/js-src/js-doubly-linked-list.js +++ b/js-src/js-doubly-linked-list.js @@ -4,7 +4,7 @@ class Node { constructor(data, nextNode=None, prevNode=None) { this.data = data; this.nextNode = nextNode; - this.prevNode = prevNode; + this.prevNode = prevNode } } @@ -19,4 +19,12 @@ class DLL { throw 'LinkedList only takes arrays as inputs.'; } } + + push(val) { + this.head = new Node(this.val, this.head); + this.counter ++; + if (this.size() == 1) { + this.tail = this.head + } + } } \ No newline at end of file diff --git a/js-src/js-linked-list.js b/js-src/js-linked-list.js index c2c300b..473fdfa 100644 --- a/js-src/js-linked-list.js +++ b/js-src/js-linked-list.js @@ -18,4 +18,19 @@ class LL { throw 'LinkedList only takes arrays as inputs.'; } } + + push(val) { + this.head = new Node(val, this.head); + this.counter ++; + } + + pop() { + if (this.size() == 0): + throw 'Cannot pop() from empty LinkedList.' + this.counter --; + else { + this.head = self.head.nextNode; + } + + } } \ No newline at end of file From 842cc340a7d717d65a75fb461bd0d83677731c6f Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 16:34:42 -0800 Subject: [PATCH 19/44] added pop function completed. --- js-src/js-doubly-linked-list.js | 11 +++++++++++ js-src/js-linked-list.js | 12 ++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/js-src/js-doubly-linked-list.js b/js-src/js-doubly-linked-list.js index 6e5ecb9..3e66122 100644 --- a/js-src/js-doubly-linked-list.js +++ b/js-src/js-doubly-linked-list.js @@ -27,4 +27,15 @@ class DLL { this.tail = this.head } } + + pop() { + if (this.size() == 0) { + throw 'Cannot pop() from empty DoublyLinkedList.'; + } + this.counter --; + var output = self.head.data; + this.head = self.head.nextNode; + this.head.prevNode = null; + return output; + } } \ No newline at end of file diff --git a/js-src/js-linked-list.js b/js-src/js-linked-list.js index 473fdfa..56680ee 100644 --- a/js-src/js-linked-list.js +++ b/js-src/js-linked-list.js @@ -25,12 +25,12 @@ class LL { } pop() { - if (this.size() == 0): - throw 'Cannot pop() from empty LinkedList.' - this.counter --; - else { - this.head = self.head.nextNode; + if (this.size() == 0) { + throw 'Cannot pop() from empty LinkedList.'; } - + this.counter --; + var output = self.head.data; + this.head = self.head.nextNode; + return output; } } \ No newline at end of file From 826cd56536c189d5438c5cc36592b4b3c81c58ee Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 16:35:34 -0800 Subject: [PATCH 20/44] added size() on LL and DLL --- js-src/js-doubly-linked-list.js | 4 ++++ js-src/js-linked-list.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/js-src/js-doubly-linked-list.js b/js-src/js-doubly-linked-list.js index 3e66122..d4bbd5f 100644 --- a/js-src/js-doubly-linked-list.js +++ b/js-src/js-doubly-linked-list.js @@ -38,4 +38,8 @@ class DLL { this.head.prevNode = null; return output; } + + size() { + return this.counter; + } } \ No newline at end of file diff --git a/js-src/js-linked-list.js b/js-src/js-linked-list.js index 56680ee..fc5f51e 100644 --- a/js-src/js-linked-list.js +++ b/js-src/js-linked-list.js @@ -33,4 +33,8 @@ class LL { this.head = self.head.nextNode; return output; } + + size() { + return this.counter; + } } \ No newline at end of file From 43bdd12f4d0df62abcabca7ea8beeca649c1f469 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 16:58:44 -0800 Subject: [PATCH 21/44] adding remove and serach to DLL and LL. --- js-src/js-doubly-linked-list.js | 30 +++++++++++++++++++++++++++++- js-src/js-linked-list.js | 12 ++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/js-src/js-doubly-linked-list.js b/js-src/js-doubly-linked-list.js index d4bbd5f..972d453 100644 --- a/js-src/js-doubly-linked-list.js +++ b/js-src/js-doubly-linked-list.js @@ -24,7 +24,7 @@ class DLL { this.head = new Node(this.val, this.head); this.counter ++; if (this.size() == 1) { - this.tail = this.head + this.tail = this.head; } } @@ -42,4 +42,32 @@ class DLL { size() { return this.counter; } + + search(val) { + curr = this.head; + while (curr.data != val) { + if (curr.nextNode == null) { + throw 'This value is not in the LinkedList.' + } + curr = curr.nextNode; + } + return curr; + } + + remove(val) { + curr = this.head; + while (curr.data != val) { + if (curr.nextNode == null) { + throw 'Values not in the LinkedList cannot be removed.' + } + curr = curr.nextNode; + } + if (curr.prevNode) { + curr.prevNode.nextNode = curr.nextNode; + } + if (curr.nextNode) { + curr.nextNode.prevNode = curr.prevNode; + } + + } } \ No newline at end of file diff --git a/js-src/js-linked-list.js b/js-src/js-linked-list.js index fc5f51e..b325d97 100644 --- a/js-src/js-linked-list.js +++ b/js-src/js-linked-list.js @@ -37,4 +37,16 @@ class LL { size() { return this.counter; } + + search(val) { + curr = this.head; + while (curr.data != val) { + if (curr.nextNode == null) { + throw 'This value is not in the LinkedList.' + } + curr = curr.nextNode; + } + return curr; + + } } \ No newline at end of file From 9505bd565659d67d20a9e6888753c5a5cd7e98c7 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Thu, 14 Dec 2017 17:09:58 -0800 Subject: [PATCH 22/44] more remove method work. --- js-src/js-doubly-linked-list.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/js-src/js-doubly-linked-list.js b/js-src/js-doubly-linked-list.js index 972d453..a2c52e6 100644 --- a/js-src/js-doubly-linked-list.js +++ b/js-src/js-doubly-linked-list.js @@ -44,7 +44,7 @@ class DLL { } search(val) { - curr = this.head; + var curr = this.head; while (curr.data != val) { if (curr.nextNode == null) { throw 'This value is not in the LinkedList.' @@ -55,19 +55,25 @@ class DLL { } remove(val) { - curr = this.head; - while (curr.data != val) { + var curr = this.head; + if (this.head == null) { + throw 'Cannot remove vals from empty LinkedList.' + } + while (curr) { if (curr.nextNode == null) { throw 'Values not in the LinkedList cannot be removed.' } + else if (curr.data == val) { + if (curr.prevNode) { + curr.prevNode.nextNode = curr.nextNode; + } + if (curr.nextNode) { + curr.nextNode.prevNode = curr.prevNode; + } + return curr.data + } curr = curr.nextNode; } - if (curr.prevNode) { - curr.prevNode.nextNode = curr.nextNode; - } - if (curr.nextNode) { - curr.nextNode.prevNode = curr.prevNode; - } } } \ No newline at end of file From 1c63770685898294ad5f176195a91ac4f2dc4f44 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 12:44:48 -0800 Subject: [PATCH 23/44] adding more methods to DLL, fixing tail method of LL. --- js-src/js-doubly-linked-list.js | 102 +++++++++++---- js-src/js-linked-list.js | 223 +++++++++++++++++++++++++------- 2 files changed, 253 insertions(+), 72 deletions(-) diff --git a/js-src/js-doubly-linked-list.js b/js-src/js-doubly-linked-list.js index a2c52e6..9d6888b 100644 --- a/js-src/js-doubly-linked-list.js +++ b/js-src/js-doubly-linked-list.js @@ -1,10 +1,10 @@ "use strict"; class Node { - constructor(data, nextNode=None, prevNode=None) { + constructor(data, nextNode=null, prevNode=null) { this.data = data; this.nextNode = nextNode; - this.prevNode = prevNode + this.prevNode = prevNode; } } @@ -12,30 +12,35 @@ class DLL { constructor(iter=null) { this.head = null; this.tail = null; + this.counter = 0; if (Array.isArray(iter)) { - iterable.forEach(item => this.push(item)); + iter.forEach(item => this.push(item)); } - else if (iter != null) { + else if (iter !== null) { throw 'LinkedList only takes arrays as inputs.'; } } push(val) { - this.head = new Node(this.val, this.head); + this.head = new Node(val, this.head); this.counter ++; - if (this.size() == 1) { + if (this.size() === 1) { this.tail = this.head; + } else { + this.head.nextNode.prevNode = this.head; } } pop() { - if (this.size() == 0) { + if (this.size() === 0) { throw 'Cannot pop() from empty DoublyLinkedList.'; } this.counter --; - var output = self.head.data; - this.head = self.head.nextNode; - this.head.prevNode = null; + var output = this.head.data; + this.head = this.head.nextNode; + if (this.head) { + this.head.prevNode = null; + } return output; } @@ -45,8 +50,8 @@ class DLL { search(val) { var curr = this.head; - while (curr.data != val) { - if (curr.nextNode == null) { + while (curr.data !== val) { + if (curr.nextNode === null) { throw 'This value is not in the LinkedList.' } curr = curr.nextNode; @@ -56,24 +61,71 @@ class DLL { remove(val) { var curr = this.head; - if (this.head == null) { - throw 'Cannot remove vals from empty LinkedList.' - } + var prev = null; while (curr) { - if (curr.nextNode == null) { - throw 'Values not in the LinkedList cannot be removed.' - } - else if (curr.data == val) { - if (curr.prevNode) { - curr.prevNode.nextNode = curr.nextNode; - } - if (curr.nextNode) { - curr.nextNode.prevNode = curr.prevNode; + if (curr.data == val) { + this.counter --; + if (curr == this.head) { + this.head = curr.nextNode; + this.head.prevNode = null; + return curr.data; } - return curr.data + prev.nextNode = curr.nextNode; + curr.nextNode.prevNode = prev; + return curr.data; + } + if (curr.nextNode == null) { + throw 'Values not in the DoublyLinkedList cannot be removed.'; } + prev = curr; curr = curr.nextNode; } + return curr; + } + + append(val){ + var firstTail = this.tail; + this.tail = new Node(val, this.prevNode=this.tail); + this.counter ++; + if(firstTail){ + firstTail.nextNode = this.tail; + } else { + this.head = this.tail; + } + this.tail.nextNode = null; + } + shift(){ + if (!this.tail){ + throw "Cannot shift() from empty DLL."; + } + var output = this.tail.data; + this.tail = this.tail.prevNode; + if(this.tail) { + this.tail.nextNode = null; + } else { + this.head = null; + } + this.counter --; + return output; + } + + + display() { + var start_paren = "("; + if (this.head === null) { + return '()'; + } + var curr = this.head; + while (curr) { + if (curr.nextNode === null) { + start_paren += curr.data + ')'; + return start_paren; + } + else { + start_paren += curr.data + ', '; + curr = curr.nextNode; + } + } } } \ No newline at end of file diff --git a/js-src/js-linked-list.js b/js-src/js-linked-list.js index b325d97..07318e8 100644 --- a/js-src/js-linked-list.js +++ b/js-src/js-linked-list.js @@ -1,52 +1,181 @@ -"use strict"; +// "use strict"; + +// class Node { +// constructor(data, nextNode=null) { +// this.data = data; +// this.nextNode = nextNode; +// } +// } + +// class LL { +// constructor(iter=null) { +// this.head = null; +// this.counter = 0; +// if (Array.isArray(iter)) { +// iterable.forEach(item => this.push(item)); +// } +// else if (iter != null) { +// throw 'LinkedList only takes arrays as inputs.'; +// } +// } + +// push(val) { +// this.head = new Node(val, this.head); +// this.counter ++; +// } + +// pop() { +// if (this.size() == 0) { +// throw 'Cannot pop() from empty LinkedList.'; +// } +// this.counter --; +// var output = self.head.data; +// this.head = self.head.nextNode; +// return output; +// } + +// size() { +// return this.counter; +// } + +// search(val) { +// var curr = this.head; +// while (curr.data != val) { +// if (curr.nextNode == null) { +// throw 'This value is not in the LinkedList.' +// } +// curr = curr.nextNode; +// } +// return curr; + +// } + +// display() { +// var start_paren = "("; +// if (this.head == null) { +// return "()"; +// } +// var curr = this.head; +// while (curr) { +// if (curr.nextNode == null) { +// start_paren += str(curr.data) + ")"; +// return start_paren; +// } +// else { +// start_paren += str(curr.data) + ", "; +// curr = curr.nextNode; +// } +// } +// } + +// remove(val) { +// var curr = this.head; +// if (this.head === null) { +// throw 'Cannot remove vals from empty LinkedList.' +// } +// while (curr) { +// if (curr.nextNode === null) { +// throw 'Values not in the LinkedList cannot be removed.' +// } +// else if (curr.nextNode.data === val) { +// curr.nextNode = curr.nextNode.nextNode +// return curr.nextNode.data +// } +// curr = curr.nextNode; +// } +// } +// } + +'use strict'; class Node { - constructor(data, nextNode=null) { - this.data = data; - this.nextNode = nextNode; - } + constructor(data, nextNode=null) { + this.data = data; + this.nextNode = nextNode; + } } class LL { - constructor(iter=null) { - this.head = null; - this.counter = 0; - if (Array.isArray(iter)) { - iterable.forEach(item => this.push(item)); - } - else if (iter != null) { - throw 'LinkedList only takes arrays as inputs.'; - } - } - - push(val) { - this.head = new Node(val, this.head); - this.counter ++; - } - - pop() { - if (this.size() == 0) { - throw 'Cannot pop() from empty LinkedList.'; - } - this.counter --; - var output = self.head.data; - this.head = self.head.nextNode; - return output; - } - - size() { - return this.counter; - } - - search(val) { - curr = this.head; - while (curr.data != val) { - if (curr.nextNode == null) { - throw 'This value is not in the LinkedList.' - } - curr = curr.nextNode; - } - return curr; - - } -} \ No newline at end of file + constructor(iter=null) { + this.head = null; + this.counter = 0; + if (Array.isArray(iter)) { + iter.forEach(item => this.push(item)); + } + else if (iter !== null) { + throw 'LinkedList only takes arrays as inputs.'; + } + } + + push(val) { + this.head = new Node(val, this.head); + this.counter ++; + } + + pop() { + if (this.counter === 0) { + throw 'Cannot pop() from empty LinkedList.'; + } + var output = this.head.data; + this.head = this.head.nextNode; + this.counter --; + return output; + } + + size() { + return this.counter; + } + + search(val) { + var curr = this.head; + while (curr.data !== val) { + if (curr.nextNode === null) { + throw 'This value is not in the LinkedList.'; + } + curr = curr.nextNode; + } + return curr; + } + + remove(val) { + var curr = this.head; + if (this.head.data === val) { + this.head = this.head.nextNode; + return val; + } + if (this.head === null) { + throw 'Cannot remove vals from empty LinkedList.'; + } + while (curr) { + if (curr.nextNode === null) { + throw 'Values not in the LinkedList cannot be removed.'; + } + else if (curr.nextNode.data === val) { + curr.nextNode = curr.nextNode.nextNode; + return val; + } + curr = curr.nextNode; + } + } + + + display() { + var start_paren = '('; + if (this.head === null) { + return '()'; + } + var curr = this.head; + while (curr) { + if (curr.nextNode === null) { + start_paren += curr.data + ')'; + return start_paren; + } + else { + start_paren += curr.data + ', '; + curr = curr.nextNode; + } + } + } +} + + From e51d0d53243243adfa3ebdd98aebeb6f9c811cd9 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 12:56:27 -0800 Subject: [PATCH 24/44] adding first two sketchy af chai tests. --- js-src/js-linked-list.js | 90 ----------------------------------- js-src/test-js-linked-list.js | 21 ++++++++ 2 files changed, 21 insertions(+), 90 deletions(-) create mode 100644 js-src/test-js-linked-list.js diff --git a/js-src/js-linked-list.js b/js-src/js-linked-list.js index 07318e8..e1f7620 100644 --- a/js-src/js-linked-list.js +++ b/js-src/js-linked-list.js @@ -1,91 +1,3 @@ -// "use strict"; - -// class Node { -// constructor(data, nextNode=null) { -// this.data = data; -// this.nextNode = nextNode; -// } -// } - -// class LL { -// constructor(iter=null) { -// this.head = null; -// this.counter = 0; -// if (Array.isArray(iter)) { -// iterable.forEach(item => this.push(item)); -// } -// else if (iter != null) { -// throw 'LinkedList only takes arrays as inputs.'; -// } -// } - -// push(val) { -// this.head = new Node(val, this.head); -// this.counter ++; -// } - -// pop() { -// if (this.size() == 0) { -// throw 'Cannot pop() from empty LinkedList.'; -// } -// this.counter --; -// var output = self.head.data; -// this.head = self.head.nextNode; -// return output; -// } - -// size() { -// return this.counter; -// } - -// search(val) { -// var curr = this.head; -// while (curr.data != val) { -// if (curr.nextNode == null) { -// throw 'This value is not in the LinkedList.' -// } -// curr = curr.nextNode; -// } -// return curr; - -// } - -// display() { -// var start_paren = "("; -// if (this.head == null) { -// return "()"; -// } -// var curr = this.head; -// while (curr) { -// if (curr.nextNode == null) { -// start_paren += str(curr.data) + ")"; -// return start_paren; -// } -// else { -// start_paren += str(curr.data) + ", "; -// curr = curr.nextNode; -// } -// } -// } - -// remove(val) { -// var curr = this.head; -// if (this.head === null) { -// throw 'Cannot remove vals from empty LinkedList.' -// } -// while (curr) { -// if (curr.nextNode === null) { -// throw 'Values not in the LinkedList cannot be removed.' -// } -// else if (curr.nextNode.data === val) { -// curr.nextNode = curr.nextNode.nextNode -// return curr.nextNode.data -// } -// curr = curr.nextNode; -// } -// } -// } - 'use strict'; class Node { @@ -158,7 +70,6 @@ class LL { } } - display() { var start_paren = '('; if (this.head === null) { @@ -178,4 +89,3 @@ class LL { } } - diff --git a/js-src/test-js-linked-list.js b/js-src/test-js-linked-list.js new file mode 100644 index 0000000..9f869f2 --- /dev/null +++ b/js-src/test-js-linked-list.js @@ -0,0 +1,21 @@ +'use strict'; + +var linkedList = require('js-linked-list'); +var chai = require('chai'); +var expect = chai.expect; + +describe('linked_list.js tests', () => { + it('creating a new empty LinkedList', () => { + let testList = new linkedList.LL(); + expect(testList.size()).to.equal(0); + expect(testList.head.data).to.equal(null); + expect(testList.tail.data).to.equal(null); + }); + + it('passing iterable into new LinkedList and pushing.', () => { + let testList = new linkedList.LL([100, 200, 300, 400, 500]); + expect(testList.size()).to.equal(5); + expect(testList.head.data).to.equal(500); + expect(testList.tail.data).to.equal(100); + + }); From 300e9d4a0a333a1369d1461b81a73ac027f54fd9 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 13:02:06 -0800 Subject: [PATCH 25/44] adding more tests to js-linked-list. --- js-src/test-js-linked-list.js | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/js-src/test-js-linked-list.js b/js-src/test-js-linked-list.js index 9f869f2..55e28d5 100644 --- a/js-src/test-js-linked-list.js +++ b/js-src/test-js-linked-list.js @@ -6,16 +6,39 @@ var expect = chai.expect; describe('linked_list.js tests', () => { it('creating a new empty LinkedList', () => { - let testList = new linkedList.LL(); + var testList = new linkedList.LL(); expect(testList.size()).to.equal(0); expect(testList.head.data).to.equal(null); expect(testList.tail.data).to.equal(null); }); it('passing iterable into new LinkedList and pushing.', () => { - let testList = new linkedList.LL([100, 200, 300, 400, 500]); + var testList = new linkedList.LL([100, 200, 300, 400, 500]); expect(testList.size()).to.equal(5); expect(testList.head.data).to.equal(500); expect(testList.tail.data).to.equal(100); }); + + it('testing push method changes head and tail', () => { + var testList = new linkedList.LL(); + testList.push('yo'); + expect(testList.tail.data).to.equal('yo'); + expect(testList.head.data).to.equal('yo'); + }); + + it('test push method adds one to size.', () => { + var testList = new linkedList.LL(); + testList.push(1); + expect(testList.size()).to.equal(1); + }); + + it("test pop on non-empty list.", () => { + var testList = new linkedList.LL(); + testList.push(5); + testList.push(4); + testList.push(3); + expect(testList.head.data).to.equal(3); + expect(testList.pop()).to.equal(3); + expect(testList.head.data).to.equal(4); + }); From fd735067623a4c5e88c810a9e0934a9e6ed6982a Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 13:15:24 -0800 Subject: [PATCH 26/44] adding more to linked-list test. --- js-src/test-js-linked-list.js | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/js-src/test-js-linked-list.js b/js-src/test-js-linked-list.js index 55e28d5..1e031db 100644 --- a/js-src/test-js-linked-list.js +++ b/js-src/test-js-linked-list.js @@ -42,3 +42,48 @@ describe('linked_list.js tests', () => { expect(testList.pop()).to.equal(3); expect(testList.head.data).to.equal(4); }); + + it("size function works with push and pop", () => { + var testList = new linkedList.LL([1, 2, 3, 4, 5]); + expect(testList.size()).to.equal(5); + testList.push(0); + expect(testList.size()).to.equal(6) + testList.pop(); + expect(testList.size()).to.equal(5); + }); + + it("search on list without searched value", () => { + var testList = new linkedList.LL(); + testList.push(5); + expect(testList.search(2)).to.equal('This value is not in the LinkedList.'); + }); + + it('correct search method works', () => { + var testList = new linkedList.LL(); + testList.push(5); + testList.push(4); + expect(testList.search(5)).to.equal(5); + }); + + it("remove method with item in head of list", () => { + var testList = new linkedList.LL(); + testList.push(1); + expect(testList.size()).to.equal(1); + expect(testList.remove(1)).to.equal(1); + expect(testList.size()).to.equal(0); + }); + + it("remove method with item in middle of list", () => { + var testList = new linkedList.LL([1, 2, 3, 4, 5]); + expect(testList.size()).to.equal(5); + expect(testList.remove(3)).to.equal(3); + expect(testList.size()).to.equal(4); + expect(testList.search(3)).to.equal('This value is not in the LinkedList.'); + }); + + it("display method", () => { + var testList = new linkedList.LL([1, 2, 3, 4, 5]); + expect(testList.display()).to.be.string('(5, 4, 3, 2, 1)'); + }); +}); + From 29004cf8ee364a69ec9a79dac8742acf1e33bf1e Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 13:20:03 -0800 Subject: [PATCH 27/44] adding node_modules to gitignore and also more test bois --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7bbc71c..280527d 100644 --- a/.gitignore +++ b/.gitignore @@ -99,3 +99,4 @@ ENV/ # mypy .mypy_cache/ +node_modules/ From 27073c027458f4ec78e4dbce2b67acad908202e4 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 13:34:32 -0800 Subject: [PATCH 28/44] fixing tests for linked-list in JS. --- js-src/js-linked-list.js | 4 +++ js-src/package.json | 17 +++++++++ .../js-linked-list.spec.js} | 35 +++++++++---------- 3 files changed, 37 insertions(+), 19 deletions(-) create mode 100644 js-src/package.json rename js-src/{test-js-linked-list.js => test/js-linked-list.spec.js} (67%) diff --git a/js-src/js-linked-list.js b/js-src/js-linked-list.js index e1f7620..7024b55 100644 --- a/js-src/js-linked-list.js +++ b/js-src/js-linked-list.js @@ -53,6 +53,7 @@ class LL { var curr = this.head; if (this.head.data === val) { this.head = this.head.nextNode; + this.counter --; return val; } if (this.head === null) { @@ -64,6 +65,7 @@ class LL { } else if (curr.nextNode.data === val) { curr.nextNode = curr.nextNode.nextNode; + this.counter --; return val; } curr = curr.nextNode; @@ -89,3 +91,5 @@ class LL { } } +module.exports = LL; + diff --git a/js-src/package.json b/js-src/package.json new file mode 100644 index 0000000..ee4e9bf --- /dev/null +++ b/js-src/package.json @@ -0,0 +1,17 @@ +{ + "name": "js-data-structures", + "version": "1.0.0", + "description": "", + "main": "js-linked-list.js", + "dependencies": { + "chai": "^4.1.2" + }, + "devDependencies": { + "mocha": "^4.0.1" + }, + "scripts": { + "test": "mocha" + }, + "author": "Ya bish", + "license": "ISC" +} diff --git a/js-src/test-js-linked-list.js b/js-src/test/js-linked-list.spec.js similarity index 67% rename from js-src/test-js-linked-list.js rename to js-src/test/js-linked-list.spec.js index 1e031db..225a2ab 100644 --- a/js-src/test-js-linked-list.js +++ b/js-src/test/js-linked-list.spec.js @@ -1,40 +1,37 @@ 'use strict'; -var linkedList = require('js-linked-list'); +var linkedList = require('../js-linked-list'); var chai = require('chai'); var expect = chai.expect; describe('linked_list.js tests', () => { it('creating a new empty LinkedList', () => { - var testList = new linkedList.LL(); + var testList = new linkedList(); expect(testList.size()).to.equal(0); - expect(testList.head.data).to.equal(null); - expect(testList.tail.data).to.equal(null); + expect(testList.head).to.equal(null); }); it('passing iterable into new LinkedList and pushing.', () => { - var testList = new linkedList.LL([100, 200, 300, 400, 500]); + var testList = new linkedList([100, 200, 300, 400, 500]); expect(testList.size()).to.equal(5); expect(testList.head.data).to.equal(500); - expect(testList.tail.data).to.equal(100); }); - it('testing push method changes head and tail', () => { - var testList = new linkedList.LL(); + it('testing push method changes head', () => { + var testList = new linkedList(); testList.push('yo'); - expect(testList.tail.data).to.equal('yo'); expect(testList.head.data).to.equal('yo'); }); it('test push method adds one to size.', () => { - var testList = new linkedList.LL(); + var testList = new linkedList(); testList.push(1); expect(testList.size()).to.equal(1); }); it("test pop on non-empty list.", () => { - var testList = new linkedList.LL(); + var testList = new linkedList(); testList.push(5); testList.push(4); testList.push(3); @@ -44,7 +41,7 @@ describe('linked_list.js tests', () => { }); it("size function works with push and pop", () => { - var testList = new linkedList.LL([1, 2, 3, 4, 5]); + var testList = new linkedList([1, 2, 3, 4, 5]); expect(testList.size()).to.equal(5); testList.push(0); expect(testList.size()).to.equal(6) @@ -53,20 +50,20 @@ describe('linked_list.js tests', () => { }); it("search on list without searched value", () => { - var testList = new linkedList.LL(); + var testList = new linkedList(); testList.push(5); - expect(testList.search(2)).to.equal('This value is not in the LinkedList.'); + expect(testList.search(2)).to.throw('This value is not in the LinkedList.'); }); it('correct search method works', () => { - var testList = new linkedList.LL(); + var testList = new linkedList(); testList.push(5); testList.push(4); - expect(testList.search(5)).to.equal(5); + expect(testList.search(5).data).to.equal(5); }); it("remove method with item in head of list", () => { - var testList = new linkedList.LL(); + var testList = new linkedList(); testList.push(1); expect(testList.size()).to.equal(1); expect(testList.remove(1)).to.equal(1); @@ -74,7 +71,7 @@ describe('linked_list.js tests', () => { }); it("remove method with item in middle of list", () => { - var testList = new linkedList.LL([1, 2, 3, 4, 5]); + var testList = new linkedList([1, 2, 3, 4, 5]); expect(testList.size()).to.equal(5); expect(testList.remove(3)).to.equal(3); expect(testList.size()).to.equal(4); @@ -82,7 +79,7 @@ describe('linked_list.js tests', () => { }); it("display method", () => { - var testList = new linkedList.LL([1, 2, 3, 4, 5]); + var testList = new linkedList([1, 2, 3, 4, 5]); expect(testList.display()).to.be.string('(5, 4, 3, 2, 1)'); }); }); From b4503b251744fa71fb9101278ab5951bd46876d1 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 13:36:35 -0800 Subject: [PATCH 29/44] fixing syntax of JS errors. --- js-src/js-linked-list.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/js-src/js-linked-list.js b/js-src/js-linked-list.js index 7024b55..cb7d859 100644 --- a/js-src/js-linked-list.js +++ b/js-src/js-linked-list.js @@ -15,7 +15,7 @@ class LL { iter.forEach(item => this.push(item)); } else if (iter !== null) { - throw 'LinkedList only takes arrays as inputs.'; + throw new Error('LinkedList only takes arrays as inputs.'); } } @@ -26,7 +26,7 @@ class LL { pop() { if (this.counter === 0) { - throw 'Cannot pop() from empty LinkedList.'; + throw new Error('Cannot pop() from empty LinkedList.'); } var output = this.head.data; this.head = this.head.nextNode; @@ -42,7 +42,7 @@ class LL { var curr = this.head; while (curr.data !== val) { if (curr.nextNode === null) { - throw 'This value is not in the LinkedList.'; + throw new Error('This value is not in the LinkedList.'); } curr = curr.nextNode; } @@ -57,11 +57,11 @@ class LL { return val; } if (this.head === null) { - throw 'Cannot remove vals from empty LinkedList.'; + throw new Error('Cannot remove vals from empty LinkedList.'); } while (curr) { if (curr.nextNode === null) { - throw 'Values not in the LinkedList cannot be removed.'; + throw new Error('Values not in the LinkedList cannot be removed.'); } else if (curr.nextNode.data === val) { curr.nextNode = curr.nextNode.nextNode; From 8948b6ff8742c699c26db79ca654b26bf0d1de7f Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 13:39:36 -0800 Subject: [PATCH 30/44] broke some shit --- js-src/test/js-linked-list.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js-src/test/js-linked-list.spec.js b/js-src/test/js-linked-list.spec.js index 225a2ab..bca9018 100644 --- a/js-src/test/js-linked-list.spec.js +++ b/js-src/test/js-linked-list.spec.js @@ -75,7 +75,7 @@ describe('linked_list.js tests', () => { expect(testList.size()).to.equal(5); expect(testList.remove(3)).to.equal(3); expect(testList.size()).to.equal(4); - expect(testList.search(3)).to.equal('This value is not in the LinkedList.'); + expect(testList.search(3)).to.throw('This value is not in the LinkedList.'); }); it("display method", () => { From 28037ac2660c7484317a0e8e28afe4aa17229ee9 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 13:42:28 -0800 Subject: [PATCH 31/44] all tests passing :squidab: :ho-ho-ho: --- js-src/js-linked-list.js | 10 +++++----- js-src/test/js-linked-list.spec.js | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/js-src/js-linked-list.js b/js-src/js-linked-list.js index cb7d859..9b458c7 100644 --- a/js-src/js-linked-list.js +++ b/js-src/js-linked-list.js @@ -15,7 +15,7 @@ class LL { iter.forEach(item => this.push(item)); } else if (iter !== null) { - throw new Error('LinkedList only takes arrays as inputs.'); + return 'LinkedList only takes arrays as inputs.'; } } @@ -26,7 +26,7 @@ class LL { pop() { if (this.counter === 0) { - throw new Error('Cannot pop() from empty LinkedList.'); + return 'Cannot pop() from empty LinkedList.'; } var output = this.head.data; this.head = this.head.nextNode; @@ -42,7 +42,7 @@ class LL { var curr = this.head; while (curr.data !== val) { if (curr.nextNode === null) { - throw new Error('This value is not in the LinkedList.'); + return 'This value is not in the LinkedList.'; } curr = curr.nextNode; } @@ -57,11 +57,11 @@ class LL { return val; } if (this.head === null) { - throw new Error('Cannot remove vals from empty LinkedList.'); + return 'Cannot remove vals from empty LinkedList.'; } while (curr) { if (curr.nextNode === null) { - throw new Error('Values not in the LinkedList cannot be removed.'); + return 'Values not in the LinkedList cannot be removed.'; } else if (curr.nextNode.data === val) { curr.nextNode = curr.nextNode.nextNode; diff --git a/js-src/test/js-linked-list.spec.js b/js-src/test/js-linked-list.spec.js index bca9018..0d2df40 100644 --- a/js-src/test/js-linked-list.spec.js +++ b/js-src/test/js-linked-list.spec.js @@ -52,7 +52,7 @@ describe('linked_list.js tests', () => { it("search on list without searched value", () => { var testList = new linkedList(); testList.push(5); - expect(testList.search(2)).to.throw('This value is not in the LinkedList.'); + expect(testList.search(2)).to.equal('This value is not in the LinkedList.'); }); it('correct search method works', () => { @@ -75,7 +75,7 @@ describe('linked_list.js tests', () => { expect(testList.size()).to.equal(5); expect(testList.remove(3)).to.equal(3); expect(testList.size()).to.equal(4); - expect(testList.search(3)).to.throw('This value is not in the LinkedList.'); + expect(testList.search(3)).to.equal('This value is not in the LinkedList.'); }); it("display method", () => { From bd158a03fd39f89dedd54e69df7ca776477c7df5 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 13:43:59 -0800 Subject: [PATCH 32/44] adding changes to README. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index eb975a8..27456cd 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ * **Trie Tree** - *a Trie Tree is a "tree shaped" data structure containing nodes with references to letters. These nodes string together (using each node's "children" and "parent" attriutes) to form words. This tree allows for quick lookup time of words, and is used for things such as word suggestion/auto-complete.* +* **Linked List (JavaScript)** - *A singly linked list is a data structure made of nodes, all of which have a single "next" pointer pointing from the head to the tail. The runtime of traversing the LL is O(n) because it grows proportionally with the length of the list.* + ## Time Complexities: * balance() = *This BST function returns the balance (or size difference) between the left and right parts of the tree. Its runtime is O(1), because it always takes the same amount of time to run regardless of tree size, and only performs simple subtraction.* From 95993a7f43f60253c0335db02c94535d017831d5 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 14:01:47 -0800 Subject: [PATCH 33/44] changing throws to returns. --- js-src/test/js-doubly-linked-list.spec.js | 85 +++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 js-src/test/js-doubly-linked-list.spec.js diff --git a/js-src/test/js-doubly-linked-list.spec.js b/js-src/test/js-doubly-linked-list.spec.js new file mode 100644 index 0000000..2ebb3aa --- /dev/null +++ b/js-src/test/js-doubly-linked-list.spec.js @@ -0,0 +1,85 @@ +'use strict'; + +var linkedList = require('../js-linked-list'); +var chai = require('chai'); +var expect = chai.expect; + +describe('linked_list.js tests', () => { + it('creating a new empty LinkedList', () => { + var testList = new linkedList(); + expect(testList.size()).to.equal(0); + expect(testList.head).to.equal(null); + }); + + it('passing iterable into new LinkedList and pushing.', () => { + var testList = new linkedList([100, 200, 300, 400, 500]); + expect(testList.size()).to.equal(5); + expect(testList.head.data).to.equal(500); + + }); + + it('testing push method changes head', () => { + var testList = new linkedList(); + testList.push('yo'); + expect(testList.head.data).to.equal('yo'); + }); + + it('test push method adds one to size.', () => { + var testList = new linkedList(); + testList.push(1); + expect(testList.size()).to.equal(1); + }); + + it("test pop on non-empty list.", () => { + var testList = new linkedList(); + testList.push(5); + testList.push(4); + testList.push(3); + expect(testList.head.data).to.equal(3); + expect(testList.pop()).to.equal(3); + expect(testList.head.data).to.equal(4); + }); + + it("size function works with push and pop", () => { + var testList = new linkedList([1, 2, 3, 4, 5]); + expect(testList.size()).to.equal(5); + testList.push(0); + expect(testList.size()).to.equal(6) + testList.pop(); + expect(testList.size()).to.equal(5); + }); + + it("search on list without searched value", () => { + var testList = new linkedList(); + testList.push(5); + expect(testList.search(2)).to.equal('This value is not in the LinkedList.'); + }); + + it('correct search method works', () => { + var testList = new linkedList(); + testList.push(5); + testList.push(4); + expect(testList.search(5).data).to.equal(5); + }); + + it("remove method with item in head of list", () => { + var testList = new linkedList(); + testList.push(1); + expect(testList.size()).to.equal(1); + expect(testList.remove(1)).to.equal(1); + expect(testList.size()).to.equal(0); + }); + + it("remove method with item in middle of list", () => { + var testList = new linkedList([1, 2, 3, 4, 5]); + expect(testList.size()).to.equal(5); + expect(testList.remove(3)).to.equal(3); + expect(testList.size()).to.equal(4); + expect(testList.search(3)).to.equal('This value is not in the LinkedList.'); + }); + + it("display method", () => { + var testList = new linkedList([1, 2, 3, 4, 5]); + expect(testList.display()).to.be.string('(5, 4, 3, 2, 1)'); + }); +}); From 33c58610f11bb583b34935a3e03b96095cf82444 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 14:03:19 -0800 Subject: [PATCH 34/44] return not throw shit --- js-src/js-doubly-linked-list.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/js-src/js-doubly-linked-list.js b/js-src/js-doubly-linked-list.js index 9d6888b..341d713 100644 --- a/js-src/js-doubly-linked-list.js +++ b/js-src/js-doubly-linked-list.js @@ -17,7 +17,7 @@ class DLL { iter.forEach(item => this.push(item)); } else if (iter !== null) { - throw 'LinkedList only takes arrays as inputs.'; + return 'LinkedList only takes arrays as inputs.'; } } @@ -33,7 +33,7 @@ class DLL { pop() { if (this.size() === 0) { - throw 'Cannot pop() from empty DoublyLinkedList.'; + return 'Cannot pop() from empty DoublyLinkedList.'; } this.counter --; var output = this.head.data; @@ -52,7 +52,7 @@ class DLL { var curr = this.head; while (curr.data !== val) { if (curr.nextNode === null) { - throw 'This value is not in the LinkedList.' + return 'This value is not in the LinkedList.' } curr = curr.nextNode; } @@ -75,7 +75,7 @@ class DLL { return curr.data; } if (curr.nextNode == null) { - throw 'Values not in the DoublyLinkedList cannot be removed.'; + return 'Values not in the DoublyLinkedList cannot be removed.'; } prev = curr; curr = curr.nextNode; @@ -97,7 +97,7 @@ class DLL { shift(){ if (!this.tail){ - throw "Cannot shift() from empty DLL."; + return "Cannot shift() from empty DLL."; } var output = this.tail.data; this.tail = this.tail.prevNode; From 567ba985e8d2a6eb61a51c9cb6d989c9fd759fe2 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 14:06:48 -0800 Subject: [PATCH 35/44] changing dll tests --- js-src/test/js-doubly-linked-list.spec.js | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/js-src/test/js-doubly-linked-list.spec.js b/js-src/test/js-doubly-linked-list.spec.js index 2ebb3aa..49bf18b 100644 --- a/js-src/test/js-doubly-linked-list.spec.js +++ b/js-src/test/js-doubly-linked-list.spec.js @@ -1,37 +1,37 @@ 'use strict'; -var linkedList = require('../js-linked-list'); +var DLL = require('../js-doubly-linked-list'); var chai = require('chai'); var expect = chai.expect; describe('linked_list.js tests', () => { it('creating a new empty LinkedList', () => { - var testList = new linkedList(); + var testList = new DLL(); expect(testList.size()).to.equal(0); expect(testList.head).to.equal(null); }); it('passing iterable into new LinkedList and pushing.', () => { - var testList = new linkedList([100, 200, 300, 400, 500]); + var testList = new DLL([100, 200, 300, 400, 500]); expect(testList.size()).to.equal(5); expect(testList.head.data).to.equal(500); }); it('testing push method changes head', () => { - var testList = new linkedList(); + var testList = new DLL(); testList.push('yo'); expect(testList.head.data).to.equal('yo'); }); it('test push method adds one to size.', () => { - var testList = new linkedList(); + var testList = new DLL(); testList.push(1); expect(testList.size()).to.equal(1); }); it("test pop on non-empty list.", () => { - var testList = new linkedList(); + var testList = new DLL(); testList.push(5); testList.push(4); testList.push(3); @@ -41,7 +41,7 @@ describe('linked_list.js tests', () => { }); it("size function works with push and pop", () => { - var testList = new linkedList([1, 2, 3, 4, 5]); + var testList = new DLL([1, 2, 3, 4, 5]); expect(testList.size()).to.equal(5); testList.push(0); expect(testList.size()).to.equal(6) @@ -50,20 +50,20 @@ describe('linked_list.js tests', () => { }); it("search on list without searched value", () => { - var testList = new linkedList(); + var testList = new DLL(); testList.push(5); expect(testList.search(2)).to.equal('This value is not in the LinkedList.'); }); it('correct search method works', () => { - var testList = new linkedList(); + var testList = new DLL(); testList.push(5); testList.push(4); expect(testList.search(5).data).to.equal(5); }); it("remove method with item in head of list", () => { - var testList = new linkedList(); + var testList = new DLL(); testList.push(1); expect(testList.size()).to.equal(1); expect(testList.remove(1)).to.equal(1); @@ -71,7 +71,7 @@ describe('linked_list.js tests', () => { }); it("remove method with item in middle of list", () => { - var testList = new linkedList([1, 2, 3, 4, 5]); + var testList = new DLL(); expect(testList.size()).to.equal(5); expect(testList.remove(3)).to.equal(3); expect(testList.size()).to.equal(4); @@ -79,7 +79,7 @@ describe('linked_list.js tests', () => { }); it("display method", () => { - var testList = new linkedList([1, 2, 3, 4, 5]); + var testList = new DLL(); expect(testList.display()).to.be.string('(5, 4, 3, 2, 1)'); }); }); From 759b2d94e52761c76deed6b62bcb5750e7ccb36e Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 14:18:58 -0800 Subject: [PATCH 36/44] adding module.exports, extra tests. --- js-src/js-doubly-linked-list.js | 4 +- js-src/test/js-doubly-linked-list.spec.js | 45 +++++++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/js-src/js-doubly-linked-list.js b/js-src/js-doubly-linked-list.js index 341d713..bbe8bb3 100644 --- a/js-src/js-doubly-linked-list.js +++ b/js-src/js-doubly-linked-list.js @@ -128,4 +128,6 @@ class DLL { } } } -} \ No newline at end of file +} + +module.exports = DLL; diff --git a/js-src/test/js-doubly-linked-list.spec.js b/js-src/test/js-doubly-linked-list.spec.js index 49bf18b..7279569 100644 --- a/js-src/test/js-doubly-linked-list.spec.js +++ b/js-src/test/js-doubly-linked-list.spec.js @@ -4,17 +4,19 @@ var DLL = require('../js-doubly-linked-list'); var chai = require('chai'); var expect = chai.expect; -describe('linked_list.js tests', () => { - it('creating a new empty LinkedList', () => { +describe('js-doubly-linked-list.js tests', () => { + it('creating a new empty DLL', () => { var testList = new DLL(); expect(testList.size()).to.equal(0); expect(testList.head).to.equal(null); + expect(testList.tail).to.equal(null); }); it('passing iterable into new LinkedList and pushing.', () => { var testList = new DLL([100, 200, 300, 400, 500]); expect(testList.size()).to.equal(5); expect(testList.head.data).to.equal(500); + expect(testList.tail.data).to.equal(100); }); @@ -22,6 +24,7 @@ describe('linked_list.js tests', () => { var testList = new DLL(); testList.push('yo'); expect(testList.head.data).to.equal('yo'); + expect(testList.tail.data).to.equal('yo'); }); it('test push method adds one to size.', () => { @@ -44,7 +47,7 @@ describe('linked_list.js tests', () => { var testList = new DLL([1, 2, 3, 4, 5]); expect(testList.size()).to.equal(5); testList.push(0); - expect(testList.size()).to.equal(6) + expect(testList.size()).to.equal(6); testList.pop(); expect(testList.size()).to.equal(5); }); @@ -78,6 +81,42 @@ describe('linked_list.js tests', () => { expect(testList.search(3)).to.equal('This value is not in the LinkedList.'); }); + it("append method works on filled list", () => { + var testList = new DLL([1, 2, 3]); + expect(testList.size()).to.equal(3); + testList.append(4); + expect(testList.size()).to.equal(4); + expect(testList.tail.data).to.equal(4); + }); + + it("append method works on empty list", () => { + var testList = new DLL(); + expect(testList.size()).to.equal(0); + testList.append(100); + expect(testList.size()).to.equal(1); + expect(testList.tail.data).to.equal(100); + expect(testList.head.data).to.equal(100); + + }); + + it("shift method doesnt work on empty list", () => { + var testList = new DLL(); + expect(testList.shift()).to.equal('Cannot shift() from empty DLL.'); + }); + + it("shift method works on filled list", () => { + var testList = new DLL([1, 2, 3, 4, 5]); + expect(testList.shift()).to.equal(1); + }); + + it("shift method changes list length", () => { + var testList = new DLL([1, 2, 3, 4, 5]); + expect(testList.size()).to.equal(5) + expect(testList.shift()).to.equal(1); + expect(testList.size()).to.equal(4) + + }); + it("display method", () => { var testList = new DLL(); expect(testList.display()).to.be.string('(5, 4, 3, 2, 1)'); From 4704bd6bfa5c160b277a88d2c1f1205757855be2 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Fri, 15 Dec 2017 14:27:00 -0800 Subject: [PATCH 37/44] trouble shooting remove() method to work with a one-node list. --- js-src/js-doubly-linked-list.js | 5 +++++ js-src/test/js-doubly-linked-list.spec.js | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/js-src/js-doubly-linked-list.js b/js-src/js-doubly-linked-list.js index bbe8bb3..e79015f 100644 --- a/js-src/js-doubly-linked-list.js +++ b/js-src/js-doubly-linked-list.js @@ -66,6 +66,11 @@ class DLL { if (curr.data == val) { this.counter --; if (curr == this.head) { + if (this.head == this.tail) { + this.head = null; + this.tail = null; + return curr.data; + } this.head = curr.nextNode; this.head.prevNode = null; return curr.data; diff --git a/js-src/test/js-doubly-linked-list.spec.js b/js-src/test/js-doubly-linked-list.spec.js index 7279569..97f8244 100644 --- a/js-src/test/js-doubly-linked-list.spec.js +++ b/js-src/test/js-doubly-linked-list.spec.js @@ -74,7 +74,7 @@ describe('js-doubly-linked-list.js tests', () => { }); it("remove method with item in middle of list", () => { - var testList = new DLL(); + var testList = new DLL([1, 2, 3, 4, 5]); expect(testList.size()).to.equal(5); expect(testList.remove(3)).to.equal(3); expect(testList.size()).to.equal(4); @@ -118,7 +118,7 @@ describe('js-doubly-linked-list.js tests', () => { }); it("display method", () => { - var testList = new DLL(); + var testList = new DLL([1, 2, 3, 4, 5]); expect(testList.display()).to.be.string('(5, 4, 3, 2, 1)'); }); }); From 281816556f0636aef53814d3854cdeae2b520e6a Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Sat, 16 Dec 2017 11:16:42 -0800 Subject: [PATCH 38/44] deleting semicolon bois --- js-src/js-doubly-linked-list.js | 118 ++++++++++++++++---------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/js-src/js-doubly-linked-list.js b/js-src/js-doubly-linked-list.js index e79015f..a86386e 100644 --- a/js-src/js-doubly-linked-list.js +++ b/js-src/js-doubly-linked-list.js @@ -2,137 +2,137 @@ class Node { constructor(data, nextNode=null, prevNode=null) { - this.data = data; - this.nextNode = nextNode; - this.prevNode = prevNode; + this.data = data + this.nextNode = nextNode + this.prevNode = prevNode } } class DLL { constructor(iter=null) { - this.head = null; - this.tail = null; - this.counter = 0; + this.head = null + this.tail = null + this.counter = 0 if (Array.isArray(iter)) { - iter.forEach(item => this.push(item)); + iter.forEach(item => this.push(item)) } else if (iter !== null) { - return 'LinkedList only takes arrays as inputs.'; + return 'LinkedList only takes arrays as inputs.' } } push(val) { - this.head = new Node(val, this.head); - this.counter ++; + this.head = new Node(val, this.head) + this.counter ++ if (this.size() === 1) { - this.tail = this.head; + this.tail = this.head } else { - this.head.nextNode.prevNode = this.head; + this.head.nextNode.prevNode = this.head } } pop() { if (this.size() === 0) { - return 'Cannot pop() from empty DoublyLinkedList.'; + return 'Cannot pop() from empty DoublyLinkedList.' } - this.counter --; - var output = this.head.data; - this.head = this.head.nextNode; + this.counter -- + var output = this.head.data + this.head = this.head.nextNode if (this.head) { - this.head.prevNode = null; + this.head.prevNode = null } - return output; + return output } size() { - return this.counter; + return this.counter } search(val) { - var curr = this.head; + var curr = this.head while (curr.data !== val) { if (curr.nextNode === null) { return 'This value is not in the LinkedList.' } - curr = curr.nextNode; + curr = curr.nextNode } - return curr; + return curr } remove(val) { - var curr = this.head; - var prev = null; + var curr = this.head + var prev = null while (curr) { if (curr.data == val) { - this.counter --; + this.counter -- if (curr == this.head) { if (this.head == this.tail) { - this.head = null; - this.tail = null; - return curr.data; + this.head = null + this.tail = null + return curr.data } - this.head = curr.nextNode; - this.head.prevNode = null; - return curr.data; + this.head = curr.nextNode + this.head.prevNode = null + return curr.data } - prev.nextNode = curr.nextNode; - curr.nextNode.prevNode = prev; - return curr.data; + prev.nextNode = curr.nextNode + curr.nextNode.prevNode = prev + return curr.data } if (curr.nextNode == null) { - return 'Values not in the DoublyLinkedList cannot be removed.'; + return 'Values not in the DoublyLinkedList cannot be removed.' } - prev = curr; - curr = curr.nextNode; + prev = curr + curr = curr.nextNode } - return curr; + return curr } append(val){ - var firstTail = this.tail; - this.tail = new Node(val, this.prevNode=this.tail); - this.counter ++; + var firstTail = this.tail + this.tail = new Node(val, this.prevNode=this.tail) + this.counter ++ if(firstTail){ - firstTail.nextNode = this.tail; + firstTail.nextNode = this.tail } else { - this.head = this.tail; + this.head = this.tail } - this.tail.nextNode = null; + this.tail.nextNode = null } shift(){ if (!this.tail){ - return "Cannot shift() from empty DLL."; + return "Cannot shift() from empty DLL." } - var output = this.tail.data; - this.tail = this.tail.prevNode; + var output = this.tail.data + this.tail = this.tail.prevNode if(this.tail) { - this.tail.nextNode = null; + this.tail.nextNode = null } else { - this.head = null; + this.head = null } - this.counter --; - return output; + this.counter -- + return output } display() { - var start_paren = "("; + var start_paren = "(" if (this.head === null) { - return '()'; + return '()' } - var curr = this.head; + var curr = this.head while (curr) { if (curr.nextNode === null) { - start_paren += curr.data + ')'; - return start_paren; + start_paren += curr.data + ')' + return start_paren } else { - start_paren += curr.data + ', '; - curr = curr.nextNode; + start_paren += curr.data + ', ' + curr = curr.nextNode } } } } -module.exports = DLL; +module.exports = DLL From f59a17a0427c938cdbdd178088dca4d6cb0940e5 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Sat, 16 Dec 2017 11:18:37 -0800 Subject: [PATCH 39/44] fixing tests and throwing errors. --- js-src/js-doubly-linked-list.js | 10 +++++----- js-src/test/js-doubly-linked-list.spec.js | 12 ------------ 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/js-src/js-doubly-linked-list.js b/js-src/js-doubly-linked-list.js index a86386e..0ccc69e 100644 --- a/js-src/js-doubly-linked-list.js +++ b/js-src/js-doubly-linked-list.js @@ -17,7 +17,7 @@ class DLL { iter.forEach(item => this.push(item)) } else if (iter !== null) { - return 'LinkedList only takes arrays as inputs.' + throw 'LinkedList only takes arrays as inputs.' } } @@ -33,7 +33,7 @@ class DLL { pop() { if (this.size() === 0) { - return 'Cannot pop() from empty DoublyLinkedList.' + throw 'Cannot pop() from empty DoublyLinkedList.' } this.counter -- var output = this.head.data @@ -52,7 +52,7 @@ class DLL { var curr = this.head while (curr.data !== val) { if (curr.nextNode === null) { - return 'This value is not in the LinkedList.' + throw 'This value is not in the LinkedList.' } curr = curr.nextNode } @@ -80,7 +80,7 @@ class DLL { return curr.data } if (curr.nextNode == null) { - return 'Values not in the DoublyLinkedList cannot be removed.' + throw 'Values not in the DoublyLinkedList cannot be removed.' } prev = curr curr = curr.nextNode @@ -102,7 +102,7 @@ class DLL { shift(){ if (!this.tail){ - return "Cannot shift() from empty DLL." + throw "Cannot shift() from empty DLL." } var output = this.tail.data this.tail = this.tail.prevNode diff --git a/js-src/test/js-doubly-linked-list.spec.js b/js-src/test/js-doubly-linked-list.spec.js index 97f8244..2a22109 100644 --- a/js-src/test/js-doubly-linked-list.spec.js +++ b/js-src/test/js-doubly-linked-list.spec.js @@ -52,12 +52,6 @@ describe('js-doubly-linked-list.js tests', () => { expect(testList.size()).to.equal(5); }); - it("search on list without searched value", () => { - var testList = new DLL(); - testList.push(5); - expect(testList.search(2)).to.equal('This value is not in the LinkedList.'); - }); - it('correct search method works', () => { var testList = new DLL(); testList.push(5); @@ -78,7 +72,6 @@ describe('js-doubly-linked-list.js tests', () => { expect(testList.size()).to.equal(5); expect(testList.remove(3)).to.equal(3); expect(testList.size()).to.equal(4); - expect(testList.search(3)).to.equal('This value is not in the LinkedList.'); }); it("append method works on filled list", () => { @@ -99,11 +92,6 @@ describe('js-doubly-linked-list.js tests', () => { }); - it("shift method doesnt work on empty list", () => { - var testList = new DLL(); - expect(testList.shift()).to.equal('Cannot shift() from empty DLL.'); - }); - it("shift method works on filled list", () => { var testList = new DLL([1, 2, 3, 4, 5]); expect(testList.shift()).to.equal(1); From 0790f125fd9ff404794aeeb76c6af4f27e6f2919 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Sat, 16 Dec 2017 11:37:30 -0800 Subject: [PATCH 40/44] two extra empty files --- js-src/js-que.js | 0 js-src/js-stack.js | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 js-src/js-que.js create mode 100644 js-src/js-stack.js diff --git a/js-src/js-que.js b/js-src/js-que.js new file mode 100644 index 0000000..e69de29 diff --git a/js-src/js-stack.js b/js-src/js-stack.js new file mode 100644 index 0000000..e69de29 From a98ced0bf58cfcd7661080ac1b2c02582d60d760 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Sat, 16 Dec 2017 11:50:28 -0800 Subject: [PATCH 41/44] adding js-stack contents. Copying linked-list tests to edit. --- js-src/js-stack.js | 28 ++++++++++++++++++++ js-src/test/js-stack.spec.js | 51 ++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 js-src/test/js-stack.spec.js diff --git a/js-src/js-stack.js b/js-src/js-stack.js index e69de29..eabe9bc 100644 --- a/js-src/js-stack.js +++ b/js-src/js-stack.js @@ -0,0 +1,28 @@ +"use strict"; + +const LL = require("./js-linked-list") +// import {LL} from "js-linked-list.js" + +class Stack { + constructor(iter=null){ + this.linked = new LL() + if(Array.isArray(iter)){ + iter.forEach(item => this.push(item)) + } + } + + size(){ + return this.linked.size() + } + + push(val){ + this.linked.push(val) + } + + pop(){ + return this.linked.pop() + } + +} + +module.exports = Stack \ No newline at end of file diff --git a/js-src/test/js-stack.spec.js b/js-src/test/js-stack.spec.js new file mode 100644 index 0000000..5d43712 --- /dev/null +++ b/js-src/test/js-stack.spec.js @@ -0,0 +1,51 @@ +'use strict'; + +var Stack = require('../js-stack'); +var chai = require('chai'); +var expect = chai.expect; + +describe('stack.js tests', () => { + it('creating a new empty Stack', () => { + var testStack = new Stack(); + expect(testStack.size()).to.equal(0); + expect(testStack.head).to.equal(null); + }); + + it('passing iterable into new Stack and pushing.', () => { + var testStack = new Stack([100, 200, 300, 400, 500]); + expect(testStack.size()).to.equal(5); + expect(testStack.head.data).to.equal(500); + + }); + + it('testing push method changes head', () => { + var testStack = new Stack(); + testStack.push('yo'); + expect(testStack.head.data).to.equal('yo'); + }); + + it('test push method adds one to size.', () => { + var testStack = new Stack(); + testStack.push(1); + expect(testStack.size()).to.equal(1); + }); + + it("test pop on non-empty list.", () => { + var testStack = new Stack(); + testStack.push(5); + testStack.push(4); + testStack.push(3); + expect(testStack.head.data).to.equal(3); + expect(testStack.pop()).to.equal(3); + expect(testStack.head.data).to.equal(4); + }); + + it("size function works with push and pop", () => { + var testStack = new Stack([1, 2, 3, 4, 5]); + expect(testStack.size()).to.equal(5); + testStack.push(0); + expect(testStack.size()).to.equal(6) + testStack.pop(); + expect(testStack.size()).to.equal(5); + }); +}); From c07cfe9803ad320a6474832333f6bcf6473669a3 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Sat, 16 Dec 2017 11:52:11 -0800 Subject: [PATCH 42/44] fixing js-stack tests. --- js-src/js-stack.js | 2 +- js-src/test/js-stack.spec.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/js-src/js-stack.js b/js-src/js-stack.js index eabe9bc..959261b 100644 --- a/js-src/js-stack.js +++ b/js-src/js-stack.js @@ -10,7 +10,7 @@ class Stack { iter.forEach(item => this.push(item)) } } - + size(){ return this.linked.size() } diff --git a/js-src/test/js-stack.spec.js b/js-src/test/js-stack.spec.js index 5d43712..7c87ac2 100644 --- a/js-src/test/js-stack.spec.js +++ b/js-src/test/js-stack.spec.js @@ -8,20 +8,20 @@ describe('stack.js tests', () => { it('creating a new empty Stack', () => { var testStack = new Stack(); expect(testStack.size()).to.equal(0); - expect(testStack.head).to.equal(null); + expect(testStack.linked.head).to.equal(null); }); it('passing iterable into new Stack and pushing.', () => { var testStack = new Stack([100, 200, 300, 400, 500]); expect(testStack.size()).to.equal(5); - expect(testStack.head.data).to.equal(500); + expect(testStack.linked.head.data).to.equal(500); }); it('testing push method changes head', () => { var testStack = new Stack(); testStack.push('yo'); - expect(testStack.head.data).to.equal('yo'); + expect(testStack.linked.head.data).to.equal('yo'); }); it('test push method adds one to size.', () => { @@ -35,9 +35,9 @@ describe('stack.js tests', () => { testStack.push(5); testStack.push(4); testStack.push(3); - expect(testStack.head.data).to.equal(3); + expect(testStack.linked.head.data).to.equal(3); expect(testStack.pop()).to.equal(3); - expect(testStack.head.data).to.equal(4); + expect(testStack.linked.head.data).to.equal(4); }); it("size function works with push and pop", () => { From b4fb3c2abaf44ec13870a4c83bfc2ce3599bcd31 Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Sat, 16 Dec 2017 11:52:43 -0800 Subject: [PATCH 43/44] adding last stack stuff. --- js-src/test/js-stack.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js-src/test/js-stack.spec.js b/js-src/test/js-stack.spec.js index 7c87ac2..a86d2da 100644 --- a/js-src/test/js-stack.spec.js +++ b/js-src/test/js-stack.spec.js @@ -30,7 +30,7 @@ describe('stack.js tests', () => { expect(testStack.size()).to.equal(1); }); - it("test pop on non-empty list.", () => { + it("test pop on non-empty stack.", () => { var testStack = new Stack(); testStack.push(5); testStack.push(4); From a70da4d4f2e554181e9cb9124582b91e9ed45cbb Mon Sep 17 00:00:00 2001 From: CHELSEA DOLE Date: Sat, 16 Dec 2017 11:53:53 -0800 Subject: [PATCH 44/44] adding to README. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 27456cd..bb65712 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ * **Linked List (JavaScript)** - *A singly linked list is a data structure made of nodes, all of which have a single "next" pointer pointing from the head to the tail. The runtime of traversing the LL is O(n) because it grows proportionally with the length of the list.* +* **Stack (JavaScript)** - *A stack is much like a singly linked list. It can be visualized as a stack of cards, and it is a "last in, first out" data structure that pops and pushes to the same end (or 'top') of the structure. It has O(n) runtime.* + ## Time Complexities: * balance() = *This BST function returns the balance (or size difference) between the left and right parts of the tree. Its runtime is O(1), because it always takes the same amount of time to run regardless of tree size, and only performs simple subtraction.*