diff --git a/Data-Structures/LinkList/__tests__/linked-list.test.js b/Data-Structures/LinkList/__tests__/linked-list.test.js new file mode 100644 index 0000000..b4cfe02 --- /dev/null +++ b/Data-Structures/LinkList/__tests__/linked-list.test.js @@ -0,0 +1,8 @@ +const LinkList = require('../linked-list.js'); + +xdescribe('Test', () => { + // How might we repeat this to check on types? + it('true', ()=>{ + expect(LinkList).toBeTruthy(); + }); +}); \ No newline at end of file diff --git a/Data-Structures/LinkList/linked-list.js b/Data-Structures/LinkList/linked-list.js new file mode 100644 index 0000000..e69de29 diff --git a/Data-Structures/LinkList/readme.md b/Data-Structures/LinkList/readme.md new file mode 100644 index 0000000..4da3d71 --- /dev/null +++ b/Data-Structures/LinkList/readme.md @@ -0,0 +1,22 @@ +# Singly Linked List + + + +## Challenge +Write tests to prove the following functionality: + +* Can successfully instantiate an empty linked list +* Can properly insert into the linked list +* The head property will properly point to the first node in the linked list +* Can properly insert multiple nodes into the linked list +* Will return true when finding a value within the linked list that exists +* Will return false when searching for a value in the linked list that does not exist +* Can properly return a collection of all the values that exist in the linked list + +## Approach & Efficiency + + + +## API + + \ No newline at end of file diff --git a/Data-Structures/ll-Insertions/__tests__/linked-list.test.js b/Data-Structures/ll-Insertions/__tests__/linked-list.test.js new file mode 100644 index 0000000..0146148 --- /dev/null +++ b/Data-Structures/ll-Insertions/__tests__/linked-list.test.js @@ -0,0 +1,150 @@ +const LinkedList = require('../linked-list.js'); + +xdescribe('Test', () => { + it('true', ()=>{ + expect(true).toBeTruthy(); + }); +}); + +// * Can successfully instantiate an empty linked list +xdescribe('instantiate an empty linked list', ()=>{ + let list = new LinkedList(); + it('empty list',()=>{ + expect(list).toBeTruthy(); + }); +}); + +// * Can properly insert into the linked list +xdescribe('insert into the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + + it('successfully inserts into list', ()=>{ + expect(list.head.data).toBe('yellow'); + + }); + +}); +// * The head property will properly point to the first node in the linked list +xdescribe('The head property will properly point to the first node in the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.insert('blue'); + + it('first node is correct', ()=>{ + expect(list.head.data).toBe('blue'); + }); + +}); +// * Can properly insert multiple nodes into the linked list +xdescribe('Can properly insert multiple nodes into the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.insert('blue'); + + it('successfully added head', ()=>{ + expect(list.head.data).toBe('blue'); + }); + it('successfully added 2nd value', ()=>{ + expect(list.head.next.data).toBe('yellow'); + }); +}); + +xdescribe('Will return true when finding a value within the linked list that exists', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.insert('blue'); + let searchResult = list.includes('yellow'); + let badSearchResult = list.includes('apple'); + + // Will return true when finding a value within the linked list that exists + it('Returns true for items that exist', ()=>{ + expect(searchResult).toBeTruthy(); + }); + // * Will return false when searching for a value in the linked list that does not exist + it('Returns false for items that do not exist', ()=>{ + expect(badSearchResult).toBeFalsy(); + }); +}); + + +// * Can properly return a collection of all the values that exist in the linked list +xdescribe('Can properly return a collection of all the values that exist in the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.insert('blue'); + list.insert('green'); + let allItems = list.toString(); + it('returns a collection', ()=>{ + expect(allItems).toBe('green,blue,yellow'); + }); + +}); + +// Can successfully add a node to the end of the linked list +xdescribe('Can successfully add a node to the end of the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('green'); + list.append('blue'); + + it('Items should be added to the end of the list', ()=>{ + expect(list.head.next.data).toBe('green'); + }); + // Can successfully add multiple nodes to the end of a linked list + it('Can add multiple nodes to the end of a list',()=>{ + expect(list.head.next.next.data).toBe('blue'); + }); + +}); + +// Can successfully insert a node before a node located in the middle of a linked list + +xdescribe('Can successfully insert a node before a node located in the middle of a linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('blue'); + list.insertBefore('green', 'blue'); + it('inserts in middle', ()=>{ + expect(list.head.next.data).toBe('green'); + }); + it('blue should be at the end', ()=>{ + expect(list.head.next.next.data).toBe('blue'); + }); + it('head should stay the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); +}); +// Can successfully insert a node before the first node of a linked list +xdescribe('Can successfully insert a node before a node located in the middle of a linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('blue'); + list.insertBefore('green', 'yellow'); + it('inserts at the head', ()=>{ + expect(list.head.data).toBe('green'); + }); + it('blue should be at the end', ()=>{ + expect(list.head.next.next.data).toBe('blue'); + }); + it('head should move over', ()=>{ + expect(list.head.next.data).toBe('yellow'); + }); +}); +// Can successfully insert after a node in the middle of the linked list +xdescribe('Can successfully insert a node after a node located in the middle of a linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('blue'); + list.insertAfter('green', 'yellow'); + it('head stays the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); + it('blue should be at the end', ()=>{ + expect(list.head.next.next.data).toBe('blue'); + }); + it('new node should be in the middle', ()=>{ + expect(list.head.next.data).toBe('green'); + }); +}); +// Can successfully insert a node after the last node of the linked list \ No newline at end of file diff --git a/Data-Structures/ll-Insertions/linked-list.js b/Data-Structures/ll-Insertions/linked-list.js new file mode 100644 index 0000000..2ad5141 --- /dev/null +++ b/Data-Structures/ll-Insertions/linked-list.js @@ -0,0 +1,89 @@ +const Node = require('./node.js'); + +// instantiate an empty linked list +class LinkedList { + constructor(){ + this.head = null; + } + // insert item into the beginning of the list + insert(data){ + let inserted = new Node(data); + inserted.next = this.head; + this.head = inserted; + return this.head; + } + // A function called includes which takes in a value and returns a boolean if that value exists in the linked list + includes(searchValue) { + let currentNode = this.head; + while(currentNode) { + if (currentNode.data === searchValue){ + return true; + } + currentNode = currentNode.next; + } + return false; + } + // A function called toString which takes in no arguments and returns a string representing all the values in the linked list + toString(){ + let stringList = []; + let currentNode = this.head; + while(currentNode){ + stringList.push(currentNode.data); + currentNode = currentNode.next; + } + return stringList.toString(); + + } + // A function called append which adds a Node to the end of the list + append(data){ + let appendedItem = new Node(data); + let currentNode = this.head; + if(this.head === null){ + this.head = appendedItem; + return this.head; + } else{ + while(currentNode.next){ + currentNode = currentNode.next; + } + currentNode.next = appendedItem; + } + } + insertBefore(data, before){ + let insertedItem = new Node(data); + let currentNode = this.head; + if(currentNode.data === before){ + this.insert(data); + return; + } + + while(currentNode.next){ + if(currentNode.next.data === before){ + insertedItem.next = currentNode.next; + currentNode.next = insertedItem; + return; + } + currentNode = currentNode.next; + } + + } + + insertAfter(data, after){ + let insertedItem = new Node(data); + let currentNode = this.head; + + while(currentNode){ + if(currentNode.data === after){ + insertedItem.next = currentNode.next; + currentNode.next = insertedItem; + return; + } + currentNode = currentNode.next; + } + + } + + +} + + +module.exports = LinkedList; \ No newline at end of file diff --git a/Data-Structures/ll-Insertions/node.js b/Data-Structures/ll-Insertions/node.js new file mode 100644 index 0000000..ae7d7e9 --- /dev/null +++ b/Data-Structures/ll-Insertions/node.js @@ -0,0 +1,10 @@ +'use strict'; + +class Node { + constructor(value){ + this.data = value; + this.next = null; + } +} + +module.exports = Node; \ No newline at end of file diff --git a/Data-Structures/ll-Insertions/readme.md b/Data-Structures/ll-Insertions/readme.md new file mode 100644 index 0000000..a2c5d28 --- /dev/null +++ b/Data-Structures/ll-Insertions/readme.md @@ -0,0 +1,43 @@ +# Singly Linked List + +More complex functions for singly linked lists + +## Challenge +* Have a class named Node. This class should contain: + A variable to hold data (i.e. this.data) + A variable to hold the next Node object (i.e. this.next) +* Have a class named LinkedList. This class should contain: + A variable named head which holds the Node object that starts the list + A constructor that instantiates head as an empty linked list + A function called insert which takes in a value. This function will then create a new Node object, sets the object’s data property equal to the value. The function then appends this new Node object to the beginning of the linked list (i.e. it sets a new head) + A function called includes which takes in a value and returns a boolean if that value exists in the linked list + A function called toString whcih takes in no arguments and returns a string representing all the values in the linked list + A function called append which adds a Node to the end of the list + A function called insertBefore which adds a Node before a certain Node in the list + A function called insertAfter which adds a Node after a certain Node in the list +Implement good error checking throughout your code. Create custom errors that describe what went wrong. +Structure and Testing +Any functions you write should be clean, reusable and independent component parts to the whole program. + +#### Write tests to prove the following functionality: + +* Can successfully add a node to the end of the linked list +* Can successfully add multiple nodes to the end of a linked list +* Can successfully insert a node before a node located in the middle of a linked list +* Can successfully insert a node before the first node of a linked list +* Can successfully insert after a node in the middle of the linked list +* Can successfully insert a node after the last node of the linked list + +## Approach & Efficiency + +O(n) +We never go deeper than one interation of the list so Big O(n) is still applicable + +## API + +insert(data) - Creates a new Node Object. Appends the new Node object to the beginning of the linked list +includes(searchValue) - Takes in a value as a paramenter and returns a boolean if the value exists in the linked list +toString() - Returns a string with all the values in the linked list +append(data) - Adds a node to the end of the list +insertBefore(data, before) - Adds a Node before a certain Node in the list +insertAfter(data, after) - Adds a Node after a certain Node in the list \ No newline at end of file diff --git a/Data-Structures/ll-kth-from-end/__tests__/linked-list.test.js b/Data-Structures/ll-kth-from-end/__tests__/linked-list.test.js new file mode 100644 index 0000000..dabe330 --- /dev/null +++ b/Data-Structures/ll-kth-from-end/__tests__/linked-list.test.js @@ -0,0 +1,235 @@ +const LinkedList = require('../linked-list.js'); + +describe('Test', () => { + it('true', ()=>{ + expect(true).toBeTruthy(); + }); +}); + +// * Can successfully instantiate an empty linked list +describe('instantiate an empty linked list', ()=>{ + let list = new LinkedList(); + it('empty list',()=>{ + expect(list).toBeTruthy(); + }); +}); + +// * Can properly insert into the linked list +describe('insert into the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + + it('successfully inserts into list', ()=>{ + expect(list.head.data).toBe('yellow'); + + }); + +}); +// * The head property will properly point to the first node in the linked list +describe('The head property will properly point to the first node in the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.insert('blue'); + + it('first node is correct', ()=>{ + expect(list.head.data).toBe('blue'); + }); + +}); +// * Can properly insert multiple nodes into the linked list +describe('Can properly insert multiple nodes into the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.insert('blue'); + + it('successfully added head', ()=>{ + expect(list.head.data).toBe('blue'); + }); + it('successfully added 2nd value', ()=>{ + expect(list.head.next.data).toBe('yellow'); + }); +}); + +describe('Will return true when finding a value within the linked list that exists', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.insert('blue'); + let searchResult = list.includes('yellow'); + let badSearchResult = list.includes('apple'); + + // Will return true when finding a value within the linked list that exists + it('Returns true for items that exist', ()=>{ + expect(searchResult).toBeTruthy(); + }); + // * Will return false when searching for a value in the linked list that does not exist + it('Returns false for items that do not exist', ()=>{ + expect(badSearchResult).toBeFalsy(); + }); +}); + + +// * Can properly return a collection of all the values that exist in the linked list +describe('Can properly return a collection of all the values that exist in the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.insert('blue'); + list.insert('green'); + let allItems = list.toString(); + it('returns a collection', ()=>{ + expect(allItems).toBe('green,blue,yellow'); + }); + +}); + +// Can successfully add a node to the end of the linked list +describe('Can successfully add a node to the end of the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('green'); + list.append('blue'); + + it('Items should be added to the end of the list', ()=>{ + expect(list.head.next.data).toBe('green'); + }); + // Can successfully add multiple nodes to the end of a linked list + it('Can add multiple nodes to the end of a list',()=>{ + expect(list.head.next.next.data).toBe('blue'); + }); + +}); + +// Can successfully insert a node before a node located in the middle of a linked list + +describe('Can successfully insert a node before a node located in the middle of a linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('blue'); + list.insertBefore('green', 'blue'); + it('inserts in middle', ()=>{ + expect(list.head.next.data).toBe('green'); + }); + it('blue should be at the end', ()=>{ + expect(list.head.next.next.data).toBe('blue'); + }); + it('head should stay the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); +}); +// Can successfully insert a node before the first node of a linked list +describe('Can successfully insert a node before a node located in the middle of a linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('blue'); + list.insertBefore('green', 'yellow'); + it('inserts at the head', ()=>{ + expect(list.head.data).toBe('green'); + }); + it('blue should be at the end', ()=>{ + expect(list.head.next.next.data).toBe('blue'); + }); + it('head should move over', ()=>{ + expect(list.head.next.data).toBe('yellow'); + }); +}); +// Can successfully insert after a node in the middle of the linked list +describe('Can successfully insert a node after a node located in the middle of a linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('blue'); + list.insertAfter('green', 'yellow'); + it('head stays the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); + it('blue should be at the end', ()=>{ + expect(list.head.next.next.data).toBe('blue'); + }); + it('new node should be in the middle', ()=>{ + expect(list.head.next.data).toBe('green'); + }); +}); +// Can successfully insert a node after the last node of the linked list +describe('Can successfully insert a node after last node of a linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('blue'); + list.insertAfter('green', 'blue'); + it('head stays the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); + it('green should be at the end', ()=>{ + expect(list.head.next.next.data).toBe('green'); + }); + it('blue should be in the middle', ()=>{ + expect(list.head.next.data).toBe('blue'); + }); +}); + +// Where k is greater than the length of the linked list +describe(' Where k is greater than the length of the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + let k = list.kthFromEnd(3); + + it('head stays the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); + it('k should return error', ()=>{ + expect(k).toBe('error'); + }); +}); + + +// Where k and the length of the list are the same +describe('Where k and the length of the list are the same', ()=>{ + let list = new LinkedList(); + list.insert('green'); + list.insert('yellow'); + let k = list.kthFromEnd(2); + + it('head stays the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); + it('k should return error', ()=>{ + expect(k).toBe('error'); + }); +}); + +// Where k is not a positive integer +describe('Where k is not a positive integer', ()=>{ + let list = new LinkedList(); + list.insert('green'); + list.insert('yellow'); + let k = list.kthFromEnd(-3); + it('head stays the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); + it('k should return an error message', ()=>{ + expect(k).toBe('k needs to be a postive integer'); + }); +}); +// Where the linked list is of a size 1 +describe('Where the linked list is of a size 1', ()=>{ + let list = new LinkedList(); + list.insert('green'); + let k = list.kthFromEnd(0); + it('head stays the same', ()=>{ + expect(list.head.data).toBe('green'); + }); + it('k should return green', ()=>{ + expect(k).toBe('green'); + }); +}); +// Where k is not at the end, but somewhere in the middle of the linked list +describe('Where k is not at the end, but somewhere in the middle of the linked list', ()=>{ + let list = new LinkedList(); + list.insert('green'); + list.insert('blue'); + list.insert('yellow'); + let k = list.kthFromEnd(1); + it('head stays the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); + it('k should return blue', ()=>{ + expect(k).toBe('blue'); + }); +}); \ No newline at end of file diff --git a/Data-Structures/ll-kth-from-end/linked-list.js b/Data-Structures/ll-kth-from-end/linked-list.js new file mode 100644 index 0000000..c92ec34 --- /dev/null +++ b/Data-Structures/ll-kth-from-end/linked-list.js @@ -0,0 +1,107 @@ +const Node = require('./node.js'); + +// instantiate an empty linked list +class LinkedList { + constructor(){ + this.head = null; + } + // insert item into the beginning of the list + insert(data){ + let inserted = new Node(data); + inserted.next = this.head; + this.head = inserted; + return this.head; + } + // A function called includes which takes in a value and returns a boolean if that value exists in the linked list + includes(searchValue) { + let currentNode = this.head; + while(currentNode) { + if (currentNode.data === searchValue){ + return true; + } + currentNode = currentNode.next; + } + return false; + } + // A function called toString which takes in no arguments and returns a string representing all the values in the linked list + toString(){ + let stringList = []; + let currentNode = this.head; + while(currentNode){ + stringList.push(currentNode.data); + currentNode = currentNode.next; + } + return stringList.toString(); + + } + // A function called append which adds a Node to the end of the list + append(data){ + let appendedItem = new Node(data); + let currentNode = this.head; + if(this.head === null){ + this.head = appendedItem; + return this.head; + } else{ + while(currentNode.next){ + currentNode = currentNode.next; + } + currentNode.next = appendedItem; + } + } + insertBefore(data, before){ + let insertedItem = new Node(data); + let currentNode = this.head; + if(currentNode.data === before){ + this.insert(data); + return; + } + + while(currentNode.next){ + if(currentNode.next.data === before){ + insertedItem.next = currentNode.next; + currentNode.next = insertedItem; + return; + } + currentNode = currentNode.next; + } + + } + + insertAfter(data, after){ + let insertedItem = new Node(data); + let currentNode = this.head; + + while(currentNode){ + if(currentNode.data === after){ + insertedItem.next = currentNode.next; + currentNode.next = insertedItem; + return; + } + currentNode = currentNode.next; + } + + } + + kthFromEnd(k){ + let listArray = []; + let currentNode = this.head; + while(currentNode){ + listArray.push(currentNode.data); + currentNode = currentNode.next; + } + if(k < 0){ + return 'k needs to be a postive integer'; + } + let kIndex = ((listArray.length - 1) - k); + if(kIndex < 0){ + return 'error'; + } else { + return listArray[kIndex]; + } + } + + +} + + +module.exports = LinkedList; \ No newline at end of file diff --git a/Data-Structures/ll-kth-from-end/node.js b/Data-Structures/ll-kth-from-end/node.js new file mode 100644 index 0000000..ae7d7e9 --- /dev/null +++ b/Data-Structures/ll-kth-from-end/node.js @@ -0,0 +1,10 @@ +'use strict'; + +class Node { + constructor(value){ + this.data = value; + this.next = null; + } +} + +module.exports = Node; \ No newline at end of file diff --git a/Data-Structures/ll-kth-from-end/readme.md b/Data-Structures/ll-kth-from-end/readme.md new file mode 100644 index 0000000..6e5631d --- /dev/null +++ b/Data-Structures/ll-kth-from-end/readme.md @@ -0,0 +1,31 @@ +# Singly Linked List with K-th Search Method + +More complex functions for singly linked lists + +## Challenge + +Write a method for the LinkedList class which takes a number, k, as a parameter. Return the node’s value that is k from the end of the linked list. You have access to the Node class and all the properties on the LinkedList class as well as the methods created in previous challenges. + +#### Write tests to prove the following functionality: + +* Can successfully add a node to the end of the linked list +* Can successfully add multiple nodes to the end of a linked list +* Can successfully insert a node before a node located in the middle of a linked list +* Can successfully insert a node before the first node of a linked list +* Can successfully insert after a node in the middle of the linked list +* Can successfully insert a node after the last node of the linked list + +## Approach & Efficiency + +O(n) +We never go deeper than one interation of the list so Big O(n) is still applicable + +## API + +insert(data) - Creates a new Node Object. Appends the new Node object to the beginning of the linked list +includes(searchValue) - Takes in a value as a paramenter and returns a boolean if the value exists in the linked list +toString() - Returns a string with all the values in the linked list +append(data) - Adds a node to the end of the list +insertBefore(data, before) - Adds a Node before a certain Node in the list +insertAfter(data, after) - Adds a Node after a certain Node in the list +kthFromEnd(k) - returns the value of a node at the kth index \ No newline at end of file diff --git a/Data-Structures/ll-merge/__tests__/ll-merge.test.js b/Data-Structures/ll-merge/__tests__/ll-merge.test.js new file mode 100644 index 0000000..600449c --- /dev/null +++ b/Data-Structures/ll-merge/__tests__/ll-merge.test.js @@ -0,0 +1,313 @@ +const LinkedList = require('../ll-merge.js'); + +xdescribe('Test', () => { + it('true', ()=>{ + expect(true).toBeTruthy(); + }); +}); + +// * Can successfully instantiate an empty linked list +xdescribe('instantiate an empty linked list', ()=>{ + let list = new LinkedList(); + it('empty list',()=>{ + expect(list).toBeTruthy(); + }); +}); + +// * Can properly insert into the linked list +xdescribe('insert into the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + + it('successfully inserts into list', ()=>{ + expect(list.head.data).toBe('yellow'); + + }); + +}); +// * The head property will properly point to the first node in the linked list +xdescribe('The head property will properly point to the first node in the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.insert('blue'); + + it('first node is correct', ()=>{ + expect(list.head.data).toBe('blue'); + }); + +}); +// * Can properly insert multiple nodes into the linked list +xdescribe('Can properly insert multiple nodes into the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.insert('blue'); + + it('successfully added head', ()=>{ + expect(list.head.data).toBe('blue'); + }); + it('successfully added 2nd value', ()=>{ + expect(list.head.next.data).toBe('yellow'); + }); +}); + +xdescribe('Will return true when finding a value within the linked list that exists', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.insert('blue'); + let searchResult = list.includes('yellow'); + let badSearchResult = list.includes('apple'); + + // Will return true when finding a value within the linked list that exists + it('Returns true for items that exist', ()=>{ + expect(searchResult).toBeTruthy(); + }); + // * Will return false when searching for a value in the linked list that does not exist + it('Returns false for items that do not exist', ()=>{ + expect(badSearchResult).toBeFalsy(); + }); +}); + + +// * Can properly return a collection of all the values that exist in the linked list +xdescribe('Can properly return a collection of all the values that exist in the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.insert('blue'); + list.insert('green'); + let allItems = list.toString(); + it('returns a collection', ()=>{ + expect(allItems).toBe('green,blue,yellow'); + }); + +}); + +// Can successfully add a node to the end of the linked list +xdescribe('Can successfully add a node to the end of the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('green'); + list.append('blue'); + + it('Items should be added to the end of the list', ()=>{ + expect(list.head.next.data).toBe('green'); + }); + // Can successfully add multiple nodes to the end of a linked list + it('Can add multiple nodes to the end of a list',()=>{ + expect(list.head.next.next.data).toBe('blue'); + }); + +}); + +// Can successfully insert a node before a node located in the middle of a linked list + +xdescribe('Can successfully insert a node before a node located in the middle of a linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('blue'); + list.insertBefore('green', 'blue'); + it('inserts in middle', ()=>{ + expect(list.head.next.data).toBe('green'); + }); + it('blue should be at the end', ()=>{ + expect(list.head.next.next.data).toBe('blue'); + }); + it('head should stay the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); +}); +// Can successfully insert a node before the first node of a linked list +xdescribe('Can successfully insert a node before a node located in the middle of a linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('blue'); + list.insertBefore('green', 'yellow'); + it('inserts at the head', ()=>{ + expect(list.head.data).toBe('green'); + }); + it('blue should be at the end', ()=>{ + expect(list.head.next.next.data).toBe('blue'); + }); + it('head should move over', ()=>{ + expect(list.head.next.data).toBe('yellow'); + }); +}); +// Can successfully insert after a node in the middle of the linked list +xdescribe('Can successfully insert a node after a node located in the middle of a linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('blue'); + list.insertAfter('green', 'yellow'); + it('head stays the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); + it('blue should be at the end', ()=>{ + expect(list.head.next.next.data).toBe('blue'); + }); + it('new node should be in the middle', ()=>{ + expect(list.head.next.data).toBe('green'); + }); +}); +// Can successfully insert a node after the last node of the linked list +xdescribe('Can successfully insert a node after last node of a linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + list.append('blue'); + list.insertAfter('green', 'blue'); + it('head stays the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); + it('green should be at the end', ()=>{ + expect(list.head.next.next.data).toBe('green'); + }); + it('blue should be in the middle', ()=>{ + expect(list.head.next.data).toBe('blue'); + }); +}); + +// Where k is greater than the length of the linked list +xdescribe(' Where k is greater than the length of the linked list', ()=>{ + let list = new LinkedList(); + list.insert('yellow'); + let k = list.kthFromEnd(3); + + it('head stays the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); + it('k should return error', ()=>{ + expect(k).toBe('error'); + }); +}); + + +// Where k and the length of the list are the same +xdescribe('Where k and the length of the list are the same', ()=>{ + let list = new LinkedList(); + list.insert('green'); + list.insert('yellow'); + let k = list.kthFromEnd(2); + + it('head stays the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); + it('k should return error', ()=>{ + expect(k).toBe('error'); + }); +}); + +// Where k is not a positive integer +xdescribe('Where k is not a positive integer', ()=>{ + let list = new LinkedList(); + list.insert('green'); + list.insert('yellow'); + let k = list.kthFromEnd(-3); + it('head stays the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); + it('k should return an error message', ()=>{ + expect(k).toBe('k needs to be a postive integer'); + }); +}); +// Where the linked list is of a size 1 +xdescribe('Where the linked list is of a size 1', ()=>{ + let list = new LinkedList(); + list.insert('green'); + let k = list.kthFromEnd(0); + it('head stays the same', ()=>{ + expect(list.head.data).toBe('green'); + }); + it('k should return green', ()=>{ + expect(k).toBe('green'); + }); +}); +// Where k is not at the end, but somewhere in the middle of the linked list +xdescribe('Where k is not at the end, but somewhere in the middle of the linked list', ()=>{ + let list = new LinkedList(); + list.insert('green'); + list.insert('blue'); + list.insert('yellow'); + let k = list.kthFromEnd(1); + it('head stays the same', ()=>{ + expect(list.head.data).toBe('yellow'); + }); + it('k should return blue', ()=>{ + expect(k).toBe('blue'); + }); +}); + +// Where list1 is the same length as list2 +xdescribe('Where list1 is the same length as list2', ()=>{ + let list1 = new LinkedList(); + let list2 = new LinkedList(); + list1.insert('1'); + list1.append('2'); + list2.insert('a'); + list2.append('b'); + let merged = new LinkedList(); + merged = merged.mergeLists(list1, list2); + + it('should return an alternating list', ()=>{ + expect(merged.head.data).toBe('1'); + expect(merged.head.next.data).toBe('a'); + expect(merged.head.next.next.data).toBe('2'); + expect(merged.head.next.next.next.data).toBe('b'); + }); +}); +// Where list1 is shorter than list2 +xdescribe('Where list1 is shorter than list2', ()=>{ + let list1 = new LinkedList(); + let list2 = new LinkedList(); + list1.insert('1'); + list2.insert('a'); + list2.append('b'); + let merged = new LinkedList(); + merged = merged.mergeLists(list1, list2); + + it('should return an alternating list', ()=>{ + expect(merged.head.data).toBe('a'); + expect(merged.head.next.data).toBe('1'); + expect(merged.head.next.next.data).toBe('b'); + }); +}); +// Where list1 is longer than list2 +xdescribe('Where list1 is longer than list2', ()=>{ + let list1 = new LinkedList(); + let list2 = new LinkedList(); + list1.insert('1'); + list1.append('2'); + list2.insert('a'); + let merged = new LinkedList(); + merged = merged.mergeLists(list1, list2); + + it('should return an alternating list', ()=>{ + expect(merged.head.data).toBe('1'); + expect(merged.head.next.data).toBe('a'); + expect(merged.head.next.next.data).toBe('2'); + }); +}); +// Where list1 is null +xdescribe('Where list1 is null', ()=>{ + let list1 = null; + let list2 = new LinkedList(); + list2.insert('a'); + list2.insert('b'); + let merged = new LinkedList(); + merged = merged.mergeLists(list1, list2); + + it('should return an alternating list', ()=>{ + expect(merged).toBe('Not valid Linked List'); + }); +}); +// Where both lists are of length 1 +xdescribe('Where both lists are of length 1', ()=>{ + let list1 = new LinkedList(); + let list2 = new LinkedList(); + list1.insert('1'); + list2.insert('a'); + let merged = new LinkedList(); + merged = merged.mergeLists(list1, list2); + + it('should return an alternating list', ()=>{ + expect(merged.head.data).toBe('1'); + expect(merged.head.next.data).toBe('a'); + }); +}); \ No newline at end of file diff --git a/Data-Structures/ll-merge/ll-merge.js b/Data-Structures/ll-merge/ll-merge.js new file mode 100644 index 0000000..9f5cd64 --- /dev/null +++ b/Data-Structures/ll-merge/ll-merge.js @@ -0,0 +1,141 @@ +const Node = require('./node.js'); + +// instantiate an empty linked list +class LinkedList { + constructor(){ + this.head = null; + } + // insert item into the beginning of the list + insert(data){ + let inserted = new Node(data); + inserted.next = this.head; + this.head = inserted; + return this.head; + } + // A function called includes which takes in a value and returns a boolean if that value exists in the linked list + includes(searchValue) { + let currentNode = this.head; + while(currentNode) { + if (currentNode.data === searchValue){ + return true; + } + currentNode = currentNode.next; + } + return false; + } + // A function called toString which takes in no arguments and returns a string representing all the values in the linked list + toString(){ + let stringList = []; + let currentNode = this.head; + while(currentNode){ + stringList.push(currentNode.data); + currentNode = currentNode.next; + } + return stringList.toString(); + + } + // A function called append which adds a Node to the end of the list + append(data){ + let appendedItem = new Node(data); + let currentNode = this.head; + if(this.head === null){ + this.head = appendedItem; + return this.head; + } else{ + while(currentNode.next){ + currentNode = currentNode.next; + } + currentNode.next = appendedItem; + } + } + insertBefore(data, before){ + let insertedItem = new Node(data); + let currentNode = this.head; + if(currentNode.data === before){ + this.insert(data); + return; + } + + while(currentNode.next){ + if(currentNode.next.data === before){ + insertedItem.next = currentNode.next; + currentNode.next = insertedItem; + return; + } + currentNode = currentNode.next; + } + + } + + insertAfter(data, after){ + let insertedItem = new Node(data); + let currentNode = this.head; + + while(currentNode){ + if(currentNode.data === after){ + insertedItem.next = currentNode.next; + currentNode.next = insertedItem; + return; + } + currentNode = currentNode.next; + } + + } + + kthFromEnd(k){ + let listArray = []; + let currentNode = this.head; + while(currentNode){ + listArray.push(currentNode.data); + currentNode = currentNode.next; + } + if(k < 0){ + return 'k needs to be a postive integer'; + } + let kIndex = ((listArray.length - 1) - k); + if(kIndex < 0){ + return 'error'; + } else { + return listArray[kIndex]; + } + } + mergeLists(list1, list2){ + if(list1 === null || list2 === null){ + return 'Not valid Linked List'; + } + let array1 = list1.toString().split(','); + let array2 = list2.toString().split(','); + let final = new LinkedList; + if (array1.length - array2.length > 1 || array2.length - array1.length > 1){ + return 'Linked Lists are not close enough in length'; + } + if (array1.length >= array2.length) { + let answer = []; + for(let i = 0; i < array1.length; i++) { + answer.push([array1[i], array2[i]]); + answer = [].concat.apply([], answer); + } + answer.forEach(item=>{ + final.append(item); + }); + return final; + } + if (array1.length < array2.length){ + let answer = []; + for(let i = 0; i < array2.length+1; i++){ + answer.push([array2[i], array1[i]]); + answer = [].concat.apply([], answer); + } + answer.forEach(item=>{ + final.append(item); + }); + return final; + } + return null; + } + + +} + + +module.exports = LinkedList; \ No newline at end of file diff --git a/Data-Structures/ll-merge/node.js b/Data-Structures/ll-merge/node.js new file mode 100644 index 0000000..ae7d7e9 --- /dev/null +++ b/Data-Structures/ll-merge/node.js @@ -0,0 +1,10 @@ +'use strict'; + +class Node { + constructor(value){ + this.data = value; + this.next = null; + } +} + +module.exports = Node; \ No newline at end of file diff --git a/Data-Structures/ll-merge/readme.md b/Data-Structures/ll-merge/readme.md new file mode 100644 index 0000000..b3d3bf3 --- /dev/null +++ b/Data-Structures/ll-merge/readme.md @@ -0,0 +1,18 @@ +# Merging two Singly Linked Lists + + + +## Challenge + +* Write a method called mergeLists which takes two linked lists as arguments +* Merge the two lists together such that the final linked list has nodes that alternate between the nodes from each source list +* Return the head of the new merged list +* You have access to the Node class and all the properties on the Linked List class as well as the methods created in previous challenges. + +## Approach & Efficiency + + + +## API + + diff --git a/FizzBuzzTree/README.md b/FizzBuzzTree/README.md new file mode 100644 index 0000000..369e225 --- /dev/null +++ b/FizzBuzzTree/README.md @@ -0,0 +1,22 @@ +# FizzBuzz Tree + +## Links + +- [Link to Pull Request](https://github.com/morgan-401-advanced-javascript/data-structures-and-algorithms/pull/13) +- [Link to Travis](https://travis-ci.com/morgan-401-advanced-javascript/data-structures-and-algorithms/builds/137707775) + + + +## Whiteboard + + + +## Challenge + + + +## Approach & Efficiency + + + +## API \ No newline at end of file diff --git a/FizzBuzzTree/fizzbuzz-tree.js b/FizzBuzzTree/fizzbuzz-tree.js new file mode 100644 index 0000000..04548d4 --- /dev/null +++ b/FizzBuzzTree/fizzbuzz-tree.js @@ -0,0 +1,2 @@ +'use strict'; +const Node = require('./node.js'); diff --git a/FizzBuzzTree/node.js b/FizzBuzzTree/node.js new file mode 100644 index 0000000..ebbeec3 --- /dev/null +++ b/FizzBuzzTree/node.js @@ -0,0 +1,12 @@ + +'use strict'; + +class Node { + constructor(value) { + this.data = value; + this.left = null; + this.right = null; + } +} + +module.exports = Node; \ No newline at end of file diff --git a/README.md b/README.md index f2dd06e..e35a1fc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,22 @@ # data-structures-and-algorithms ## Table of Contents - -[Array-Reverse](./challenges/arrayReverse) \ No newline at end of file +#### Challenge 1 +[1. Array-Reverse](./challenges/arrayReverse) +#### Challenge 2 +[2. Array-Shift](./challenges/ArrayShift) +#### Challenge 3 +[Array-Binary-Search](./challenges/arrayBinarySearch) +#### Challenge 5 +[Link-List](./Data-Structures/LinkList) +#### Challenge 6 +[ll-Insertions](./Data-Structures/ll-Insertions) +#### Challenge 7 +[ll-kth-from-end](./Data-Structures/ll-kth-from-end) +#### Challenge 8 +[ll-merge](./Data-Structures/ll-merge) +#### Challenge 9 +[Stack-And-Queue](./stacksAndQueues/) +#### Challenge 12 +[fifo-animal-shelter](./challenges/fifoAnimalShelter) +#### Challenge 13 +[] \ No newline at end of file diff --git a/assets/AWS-1.png b/assets/AWS-1.png new file mode 100644 index 0000000..fdccb7a Binary files /dev/null and b/assets/AWS-1.png differ diff --git a/assets/ArrayShift.jpg b/assets/ArrayShift.jpg new file mode 100644 index 0000000..af68296 Binary files /dev/null and b/assets/ArrayShift.jpg differ diff --git a/assets/CodeChallenge3.jpg b/assets/CodeChallenge3.jpg new file mode 100644 index 0000000..01dea63 Binary files /dev/null and b/assets/CodeChallenge3.jpg differ diff --git a/assets/aws terminal.png b/assets/aws terminal.png new file mode 100644 index 0000000..7336956 Binary files /dev/null and b/assets/aws terminal.png differ diff --git a/challenges/ArrayShift/README.md b/challenges/ArrayShift/README.md new file mode 100644 index 0000000..243916b --- /dev/null +++ b/challenges/ArrayShift/README.md @@ -0,0 +1,11 @@ +# Challenge Summary +insertShiftArray is a function which takes in an array and the value to be added. Without utilizing any of the built-in methods available to javascript, it return an array with the new value added at the middle index. + +## Challenge Description +Write a function called insertShiftArray which takes in an array and the value to be added. Without utilizing any of the built-in methods available to your language, return an array with the new value added at the middle index. + +## Approach & Efficiency +O(N) + +## Solution +![UML](../../assets/ArrayShift.jpg) diff --git a/challenges/ArrayShift/__tests__/array-shift.test.js b/challenges/ArrayShift/__tests__/array-shift.test.js new file mode 100755 index 0000000..5bd253c --- /dev/null +++ b/challenges/ArrayShift/__tests__/array-shift.test.js @@ -0,0 +1,19 @@ +'use strict'; + +const arrayShift = require('../array-shift.js'); + + +xdescribe('Testing challenge', () => { + it('return an array with the new value added at the middle index', () => { + expect(arrayShift([2,4,6,8], 5)).toStrictEqual([2, 4, 5, 6, 8]); + expect(arrayShift([4,8,15,23,42], 16).length).toStrictEqual(4,8,15,16, 23,42); + }); + +}); + +xdescribe('Test', () => { + // How might we repeat this to check on types? + it('true', ()=>{ + expect(true).toBeTruthy(); + }); +}); diff --git a/challenges/ArrayShift/array-shift.js b/challenges/ArrayShift/array-shift.js new file mode 100644 index 0000000..a53a1a9 --- /dev/null +++ b/challenges/ArrayShift/array-shift.js @@ -0,0 +1,32 @@ +'use strict'; +const arrayShift = {}; + +arrayShift.insertShiftArray = (a, b)=>{ + let answer = []; + let middle = 0; + if(a.length % 2 === 0){ + middle = (a.length / 2); + } else { + middle = ((a.length + 1) / 2); + } + for (let i=0; i< middle; i++){ + answer[i] = a[i]; + } + answer[middle]= b; + for (let i=middle; i< a.length; i++){ + answer[i+1] = a[i]; + } + return answer; +}; + + + +// let test1 = [2,4,6,8]; +// let test1Insert = 5; + +// let test2 = [4,8,15,23,42]; +// let test2Insert = 16; +// console.log('test 1 ', insertShiftArray(test1, test1Insert)); +// console.log('test 2 ', insertShiftArray(test2, test2Insert)); + +module.exports = arrayShift; \ No newline at end of file diff --git a/challenges/arrayBinarySearch/README.md b/challenges/arrayBinarySearch/README.md new file mode 100644 index 0000000..196a990 --- /dev/null +++ b/challenges/arrayBinarySearch/README.md @@ -0,0 +1,18 @@ +# Author: +Morgan Shaw +Nadya Ilinskaya +James Dunn + +# Binary Search +A function called BinarySearch which takes in 2 parameters: a sorted array and the search key. It returns the index of the array’s element that is equal to the search key, or -1 if the element does not exist. + +## Challenge +Write a function called BinarySearch which takes in 2 parameters: a sorted array and the search key. Without utilizing any of the built-in methods available to your language, return the index of the array’s element that is equal to the search key, or -1 if the element does not exist. + +## Approach & Efficiency +While loop through the array: Find the middle of the array. Compare the value that is located at the index = middle to the search key. Because the array is sorted we can determine to change our search parameters to the left or the right of the array. Once the index is found return the index, if the key does not exist in the array return -1. + +## Solution +[link](./array-binary-search.js) +[Repl.it](https://repl.it/repls/OrneryCurlyDividend) +![UML Diagram](../../assets/CodeChallenge3.jpg) \ No newline at end of file diff --git a/challenges/arrayBinarySearch/__tests__/arrayBinary.test.js b/challenges/arrayBinarySearch/__tests__/arrayBinary.test.js new file mode 100755 index 0000000..f90f973 --- /dev/null +++ b/challenges/arrayBinarySearch/__tests__/arrayBinary.test.js @@ -0,0 +1,67 @@ +'use strict'; +const BinarySearch = require('../array-binary-search.js'); +describe('Testing challenge', () => { + console.log('background: #222; color: #bada55', `MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWWWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWXOxxOXWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWMMMWX0xolcllox0NWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWWNKkollllcllllldkKWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWKOdllllllllllllllloxOXWMWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWXOxollllllllllllllllllllokKNWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN0kolllllllllllllllllllllllllldOXWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWKOdlllllllllllllllllllllllllllllllox0NWMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMWXOxllllllllllllllllllllllllllllllllllllldOKWMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMWN0kolllllllllllllllllllllllllllllllllllllllllox0XWMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMNKkdlllllllllllllllllllllllllllllllllllllllllllllld0WMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMWXOdllllllllllllllllllllllllllllllllllllllllllllllllxXWMMMXKWMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMWN0xolllllllllllllllllllllllllllllllllllllllllllllllllld0WWW0:'ckXWMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMWNK00Okxollllllllllllllllllllllllllllllllllllllllllllllllcc:'....,o0NMMMMMMMMMMMMMM + MMMMMMMMMMMMWNNNNNNNWWWMWX0xlllllllllllllllllllllllllllllllllllllllllllll:...........:xKWMMMMMMMMMMM + MMMMMMMMMWX0xdoooooddxkOKNWWOolllllllllllllloddolllllllllllllllllllllllld;.............'lONMMMMMMMMM + MMMMMMMNKkdllllllllllllllOWMNxlllllllllllldOXNN0ollllllllllllllllllllldKNKd'..............;dKWMMMMMM + MMMMWXOdlllllllllllllllllOWMXxllllllllllx0NMMMMKoclllllllllllllllllld0NMMWx.................'ckNMMMM + MMMMWXKKKKKkllllllllllllkNMWOllllllllld0NMMMMMNxlllllllllllllllllloONWMMMX:.............:kkkkkOXMMMM + MMMMMMMMMMMKollllllllloONMW0ollllllld0NMWNNMMNklllllllllllllllllokXWWWWMWx..............oWMMMMMMMMMM + MMMMMMMMMMMKolllllllloOWMNOolllllldONWWXO0WMWOllllllllllllllllokXWWN0KWMK:..............oWMMMMMMMMMM + MMMMMMMMMMMKollllllloOWMNklllllldONWMNOdONWW0ollllllllllllllokXWMN0dxXMWd...............oWMMMMMMMMMM + MMMMMMMMMMMKolllllloOWWNkllllldONWWNOdlkNMWKdllllllllllllldOXWMN0xlo0WM0;...............oWMMMMMMMMMM + MMMMMMMMMMMKollllloOWMNklllldONWWNOdlldKMMXxllllllllllllx0NWWN0dlllxNWNo................oWMMMMMMMMMM + MMMMMMMMMMMKolllllkNMWOllld0NWWXOdllllOWMWOlllllllllldkKNMWXOdlllldKWWO;',;:cllooddxxxxxKWMMMMMMMMMM + MMMMMMMMMMMKolllldKMMKolx0NMWXkdlllllo0MMXdlllllldxk0NWMNKkolllodx0WMMX0KNNWMMMMWWNNNNNXWMMMMMMMMMMM + MMMMMMMMMMMKollllxNMWKOKNWNKkollllllllOWMXxooxkOKNWWMNKOdooxk0KXNWMMMNXKOkxdolcc:;;;,,,,xWMMMMMMMMMM + MMMMMMMMMMMKolllldKWMWWNXOxllllllllllldKWWNNNWWMWXK0Okkk0XNWMWWXXWMM0c'.................oWMMMMMMMMMM + MMMMMMMMMMMKollllloxOOkdolllllllllllllloxO0000OkOOOOKNWMWNX0OkddOWMXl...................oWMMMMMMMMMM + MMMMMMMMMMMKollllllllllllllllllllllllllllllloxOKNWMMWXKOkdollllxNMWx....................oWMMMMMMMMMM + MMMMMMMMMMMKolllllllllllllllllllllllllllldk0XWMWXK0OxolllllllldKWWO,....................oWMMMMMMMMMM + MMMMMMMMMMMKollllllllllllllllllllllllldkKNWWNKOxollllllllllllo0WMK:.....................oWMMMMMMMMMM + MMMMMMMMMMMKollllllllllllllllllllllokKNWWNKOdllllllllllllllllOWMNl......................oWMMMMMMMMMM + MMMMMMMMMMMKolllllllllllllllllllox0NWMNKkdllllllllllllllllllkNMWx.......................oWMMMMMMMMMM + MMMMMMMMMMMKollllllllllllllllldkKWWWKOdllllllllllllllllllllxXMWk'.......................oWMMMMMMMMMM + MMMMMMMMMMMKollllllllllllllldOXWWN0xollllllllllllllllllllldXWWO,........................oWMMMMMMMMMM + MMMMMMMMMMMKollllllllllllld0NMWXOdllllllllllllllllllllllldKWW0;.........................oWMMMMMMMMMM + MMMMMMMMMMMKollllllllllldONMWXkolllllllllllllllllllllllldKWMK:..........................oWMMMMMMMMMM + MMMMMMMMMMMKolllllllllokXWWXkollllllllllllllllllllllllldKWWK:...........................oWMMMMMMMMMM + MMMMMMMMMMMKolllllllldKWMNOollllllllllllllllllllllllllxKWM0;............................oWMMMMMMMMMM + MMMMMMMMMMMKolllllllkNMWKxlllllllllllllllllllllllllllxXMWO;.............................oWMMMMMMMMMM + MMMMMMMMMMMKollllloONMNOollllllllllllllllllllllllllokNMWk'..............................oWMMMMMMMMMM + MMMMMMMMMMMN0OOOOOKWMWX0OOOOOOOOOOOOOOOOOOOOOOOOOOOKWMMXxooooooooooooooooooooooooooooooo0WMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM + `); + it('it should return the index of the array’s element that is equal to the search key', () => { + expect(BinarySearch([4,8,15,16,23], 15)).toStrictEqual(2); + }); + it('it should return -1 if the search key does not exist', () => { + expect(BinarySearch([11,22,33,44,55,66,77], 90)).toStrictEqual(-1); + }); + it('it should return the index of the array’s element that is equal to the search key', () => { + expect(BinarySearch([4,8,15,16,23,42,90], 8)).toStrictEqual(1); + }); + it('it should return the index of the array’s element that is equal to the search key', () => { + expect(BinarySearch([4,8,15,16,23,42], 42)).toStrictEqual(5); + }); +}); \ No newline at end of file diff --git a/challenges/arrayBinarySearch/array-binary-search.js b/challenges/arrayBinarySearch/array-binary-search.js new file mode 100644 index 0000000..cb87de5 --- /dev/null +++ b/challenges/arrayBinarySearch/array-binary-search.js @@ -0,0 +1,25 @@ +'Use Strict'; + +//this is the function that will search an array for a given input +const BinarySearch = (arr, search)=>{ + //check if middle index matches key + let firstIndex = 0; + let lastIndex = arr.length - 1; + while (firstIndex <= lastIndex) { + let middle = Math.floor((firstIndex + lastIndex) / 2); + if (arr[middle] === search) { + return middle; + } + if (arr[middle] > search) { + // if search is less, then firstIndex stays same + // and lastIndex changes to middle minus 1 + lastIndex = --middle; + // divide that by two, and make that new middle + } else if (arr[middle] < search) { + firstIndex = ++middle; + } + } + return -1; +}; + +module.exports = BinarySearch; diff --git a/challenges/fifoAnimalShelter/README.md b/challenges/fifoAnimalShelter/README.md new file mode 100644 index 0000000..8ecf567 --- /dev/null +++ b/challenges/fifoAnimalShelter/README.md @@ -0,0 +1,58 @@ +# Animal Shelter Queue + +## Links + +- [PR](https://github.com/morgan-401-advanced-javascript/data-structures-and-algorithms/pull/10) +- [Link to Travis](https://travis-ci.com/morgan-401-advanced-javascript/data-structures-and-algorithms/builds/135561004) + +Build a a Queue that represents an animal shelter. Creat Dog and Cat classes. + +## Challenge + +* Create a Dog and Cat class. These classes should share the following properties: + * `name:` a string representing the name of this animal + * `print():` a function that prints + * `${name}` is a good dog! if this is a Dog object + * `${name}` is a sweet cat! if this is a Cat object +* Create a Queue class called AnimalShelter which holds only Dogs and Cats + * Add a function `enqueue(animal)` which adds the specified Dog or Cat object into the shelter + * Add a function `dequeue(pref)` which dequeues either the first Dog or the first Cat object in the queue, depending on what pref is (pref may be a string that is either empty, 'cat' or 'dog') + * If pref is an empty string, dequeue the first animal in the queue, regardless of if it’s a Dog or Cat + * After you dequeue, call the `print()` function on the dequeued object +## Approach & Efficiency + +print() Big O(1) this does not traverse through the input and only performs a single task +enqueue(animal) Big O(1) this will only add an item to the back of the queue and does not traverse through the entire list. +dequeue(pref) Big O(n) this will potentially go through the entire queue if the pref animal is not actually in the queue. + +## API + +class Dog { + constructor(name){ + this.name = name; + } + + print() +} + +class Cat { + constructor(name){ + this.name = name; + } + + print() + +} + +class AnimalShelter { + constructor(){ + this.front = null; + this.rear = null; + } + + enqueue(animal) + + + dequeue(pref) + +} diff --git a/challenges/fifoAnimalShelter/__tests__/fifo-animal-shelter.test.js b/challenges/fifoAnimalShelter/__tests__/fifo-animal-shelter.test.js new file mode 100644 index 0000000..0e8f1e9 --- /dev/null +++ b/challenges/fifoAnimalShelter/__tests__/fifo-animal-shelter.test.js @@ -0,0 +1,80 @@ +const fifoAnimalShelter = require('../fifo-animal-shelter.js'); +const Dog = fifoAnimalShelter.Dog; +const Cat = fifoAnimalShelter.Cat; +const AnimalShelter = fifoAnimalShelter.AnimalShelter; + +describe('Fifo Animal Shelter Tests!', () => { + // Can successfully enqueue a Dog + it('Can successfully enqueue a Dog', ()=>{ + let dog = new Dog('Hachi'); + let home = new AnimalShelter; + home.enqueue(dog); + expect(home.front.data.name).toBe('Hachi'); + }); + // Can successfully enqueue a Cat + it('Can successfully enqueue a Cat', ()=>{ + let cat = new Cat('Luna'); + let home = new AnimalShelter; + home.enqueue(cat); + expect(home.front.data.name).toBe('Luna'); + }); + + // Error handling when you try to enqueue something that is neither a Dog nor a Cat + it('Error handling when you try to enqueue something that is neither a Dog nor a Cat', ()=>{ + let kangaroo = 'yellow kangaroo'; + let home = new AnimalShelter; + expect(home.enqueue(kangaroo)).toBe('Cats & Dogs only!'); + }); + + // Can successfully dequeue a Dog + it('Can successfully dequeue a Dog', ()=>{ + let dog = new Dog('Hachi'); + let cat = new Cat('Luna'); + let home = new AnimalShelter; + home.enqueue(dog); + home.enqueue(cat); + expect(home.dequeue('Dog')).toBe('Hachi is a good dog!'); + }); + + // Can successfully dequeue a Cat + it('Can successfully dequeue a Cat', ()=>{ + let cat = new Cat('Luna'); + let cat2 = new Cat('Mao'); + let dog = new Dog('Hachi'); + let home = new AnimalShelter; + home.enqueue(cat); + home.enqueue(cat2); + home.enqueue(dog); + home.dequeue('Dog'); + console.log(home); + expect(home.dequeue('Cat')).toBe('Luna is a sweet cat!'); + }); + + // Can successfully dequeue the front of the AnimalShelter queue when you pass no parameters to dequeue + it('Can successfully dequeue the front of the AnimalShelter queue when you pass no parameters to dequeue', ()=>{ + let cat = new Cat('Luna'); + let dog = new Dog('Hachi'); + let home = new AnimalShelter; + home.enqueue(cat); + home.enqueue(dog); + + expect(home.dequeue()).toBe('Luna is a sweet cat!'); + }); + + // Error handling when you try to dequeue something that is neither a 'cat', 'dog' or an empty string + it('Error handling when you try to dequeue something that is neither a "cat" or "dog" or an empty string', ()=>{ + let cat = new Cat('Luna'); + let home = new AnimalShelter; + home.enqueue(cat); + expect(home.dequeue('lizard')).toBe('we do not have that animal'); + }); + + // Can successfully print the resulting object from a dequeue action + it('Can successfully print the resulting object from a dequeue action', ()=>{ + let cat = new Cat('Luna'); + let home = new AnimalShelter; + home.enqueue(cat); + expect(home.dequeue('Cat')).toBe('Luna is a sweet cat!'); + }); + +}); diff --git a/challenges/fifoAnimalShelter/fifo-animal-shelter.js b/challenges/fifoAnimalShelter/fifo-animal-shelter.js new file mode 100644 index 0000000..c877bdb --- /dev/null +++ b/challenges/fifoAnimalShelter/fifo-animal-shelter.js @@ -0,0 +1,74 @@ +'Use Strict'; +const Node = require('./node.js'); + +class Dog { + constructor(name){ + this.name = name; + } + print(){ + return `${this.name} is a good dog!`; + } +} + +class Cat { + constructor(name){ + this.name = name; + } + print(){ + return `${this.name} is a sweet cat!`; + } +} + +class AnimalShelter { + constructor(){ + this.front = null; + this.rear = null; + } + enqueue(animal){ + let species = animal.constructor.name; + + if(species === 'Cat'|| species === 'Dog'){ + let newItem = new Node(animal); + if(this.rear === null){ + this.rear = newItem; + this.front = newItem; + return; + }else{ + this.rear.next = newItem; + this.rear = newItem; + return; + } + }else{ + return 'Cats & Dogs only!'; + } + } + dequeue(pref){ + + let current = this.front; + + if(current.data.constructor.name === pref || pref === undefined){ + this.temp = this.front; + this.front = this.temp.next; + return this.temp.data.print(); + } + while(current.next){ + if(current.next.data.constructor.name === pref){ + if(current.next === this.rear){ + this.temp = current.next; + current.next= current; + this.rear = current; + return this.temp.data.print(); + } + this.temp = current.next; + current.next = current.next.next; + return this.temp.data.print(); + } + current = current.next; + } + return 'we do not have that animal'; + } +} + + +module.exports = { Dog, Cat, AnimalShelter}; + diff --git a/challenges/fifoAnimalShelter/node.js b/challenges/fifoAnimalShelter/node.js new file mode 100644 index 0000000..ae7d7e9 --- /dev/null +++ b/challenges/fifoAnimalShelter/node.js @@ -0,0 +1,10 @@ +'use strict'; + +class Node { + constructor(value){ + this.data = value; + this.next = null; + } +} + +module.exports = Node; \ No newline at end of file diff --git a/package.json b/package.json index b42cee4..628ee97 100644 --- a/package.json +++ b/package.json @@ -4,13 +4,17 @@ "description": "", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "start": "node index.js", + "lint": "eslint \"**/*.js\"", + "test": "jest --verbose --coverage", + "test-watch": "jest --watchAll --verbose --coverage", + "jsdoc": "jsdoc -c ./docs/config/jsdoc.config.json" }, "repository": { "type": "git", "url": "git+https://github.com/morgan-401-advanced-javascript/data-structures-and-algorithms.git" }, - "author": "", + "author": "Morgan T Shaw", "license": "ISC", "bugs": { "url": "https://github.com/morgan-401-advanced-javascript/data-structures-and-algorithms/issues" diff --git a/stacksAndQueues/__tests__/stacks-and-queues.test.js b/stacksAndQueues/__tests__/stacks-and-queues.test.js new file mode 100644 index 0000000..c56c9df --- /dev/null +++ b/stacksAndQueues/__tests__/stacks-and-queues.test.js @@ -0,0 +1,137 @@ +const StackAndQueues = require('../stacks-and-queues.js'); + +describe('Test', () => { + it('true', ()=>{ + expect(true).toBeTruthy(); + }); +}); + +// Can successfully push onto a stack +describe('Can successfully push onto a stack', ()=>{ + let stack = new StackAndQueues.Stack(); + stack.push('a'); + it('adds to the stack', ()=>{ + expect(stack.top.data).toBe('a'); + }); + +}); +// Can successfully push multiple values onto a stack +describe('Can successfully push multiple values onto a stack', ()=>{ + let stack = new StackAndQueues.Stack(); + stack.push('a'); + stack.push('b'); + it('should be b', ()=>{ + expect(stack.top.data).toBe('b'); + }); + it('should be a', ()=>{ + expect(stack.top.next.data).toBe('a'); + }); +}); +// Can successfully pop off the stack +describe('Can successfully pop off the stack', ()=>{ + let stack = new StackAndQueues.Stack(); + stack.push('a'); + stack.push('b'); + stack.pop(); + it('should be a', ()=>{ + expect(stack.top.data).toBe('a'); + }); + it('returns pop value', ()=>{ + expect(stack.pop()).toBe('a'); + }); +}); + +// Can successfully empty a stack after multiple pops +describe('Can successfully empty a stack after multiple pops', ()=>{ + let stack = new StackAndQueues.Stack(); + stack.push('a'); + stack.push('b'); + stack.pop(); + stack.pop(); + it('should be a', ()=>{ + expect(stack.top).toBe(null); + }); +}); +// Can successfully peek the next item on the stack +describe('Can successfully peek the next item on the stack', ()=>{ + let stack = new StackAndQueues.Stack(); + stack.push('a'); + stack.push('b'); + let peekItem= stack.peek(); + + it('should be b', ()=>{ + expect(stack.top.data).toBe('b'); + }); + it('should be a', ()=>{ + expect(stack.top.next.data).toBe('a'); + }); + it('Peeked item should be b', ()=>{ + expect(peekItem).toBe('b'); + }); +}); +// Can successfully instantiate an empty stack +describe('Can successfully instantiate an empty stack', ()=>{ + let stack = new StackAndQueues.Stack(); + it('empty stack', ()=>{ + expect(stack.top).toBe(null); + }); +}); +// Can successfully enqueue into a queue +describe('Can successfully enqueue into a queue', ()=>{ + let queue = new StackAndQueues.Queue(); + queue.enqueue('a'); + queue.enqueue('b'); + queue.enqueue('c'); + it('Can successfully enqueue into a queue', ()=>{ + expect(queue.front.data).toBe('a'); + }); + // Can successfully enqueue multiple values into a queue + it('Can successfully enqueue multiple values into a queue', ()=>{ + expect(queue.front.data).toBe('a'); + expect(queue.front.next.data).toBe('b'); + expect(queue.rear.data).toBe('c'); + }); +}); + +// Can successfully dequeue out of a queue the expected value +describe('Can successfully dequeue out of a queue the expected value', ()=>{ + let queue = new StackAndQueues.Queue(); + queue.enqueue('a'); + queue.enqueue('b'); + queue.enqueue('c'); + + it('Can successfully dequeue', ()=>{ + expect(queue.dequeue()).toBe('a'); + }); +}); +// Can successfully peek into a queue, seeing the expected value +describe('Can successfully dequeue out of a queue the expected value', ()=>{ + let queue = new StackAndQueues.Queue(); + queue.enqueue('a'); + queue.enqueue('b'); + queue.enqueue('c'); + + it('Can successfully dequeue', ()=>{ + expect(queue.peek()).toBe('a'); + }); +}); +// Can successfully empty a queue after multiple dequeues +describe('Can successfully empty a queue after multiple dequeues', ()=>{ + let queue = new StackAndQueues.Queue(); + queue.enqueue('a'); + queue.enqueue('b'); + queue.dequeue(); + queue.dequeue(); + + it('Can successfully dequeue', ()=>{ + expect(queue.front).toBe(null); + }); +}); +// Can successfully instantiate an empty queue +describe('Can successfully instantiate an empty queue', ()=>{ + let queue = new StackAndQueues.Queue(); + + it('ITS ALIVE!', ()=>{ + expect(queue.front).toBe(null); + }); +}); \ No newline at end of file diff --git a/stacksAndQueues/linked-list.js b/stacksAndQueues/linked-list.js new file mode 100644 index 0000000..0c095b6 --- /dev/null +++ b/stacksAndQueues/linked-list.js @@ -0,0 +1,141 @@ +const Node = require('./node.js.js'); + +// instantiate an empty linked list +class LinkedList { + constructor(){ + this.head = null; + } + // insert item into the beginning of the list + insert(data){ + let inserted = new Node(data); + inserted.next = this.head; + this.head = inserted; + return this.head; + } + // A function called includes which takes in a value and returns a boolean if that value exists in the linked list + includes(searchValue) { + let currentNode = this.head; + while(currentNode) { + if (currentNode.data === searchValue){ + return true; + } + currentNode = currentNode.next; + } + return false; + } + // A function called toString which takes in no arguments and returns a string representing all the values in the linked list + toString(){ + let stringList = []; + let currentNode = this.head; + while(currentNode){ + stringList.push(currentNode.data); + currentNode = currentNode.next; + } + return stringList.toString(); + + } + // A function called append which adds a Node to the end of the list + append(data){ + let appendedItem = new Node(data); + let currentNode = this.head; + if(this.head === null){ + this.head = appendedItem; + return this.head; + } else{ + while(currentNode.next){ + currentNode = currentNode.next; + } + currentNode.next = appendedItem; + } + } + insertBefore(data, before){ + let insertedItem = new Node(data); + let currentNode = this.head; + if(currentNode.data === before){ + this.insert(data); + return; + } + + while(currentNode.next){ + if(currentNode.next.data === before){ + insertedItem.next = currentNode.next; + currentNode.next = insertedItem; + return; + } + currentNode = currentNode.next; + } + + } + + insertAfter(data, after){ + let insertedItem = new Node(data); + let currentNode = this.head; + + while(currentNode){ + if(currentNode.data === after){ + insertedItem.next = currentNode.next; + currentNode.next = insertedItem; + return; + } + currentNode = currentNode.next; + } + + } + + kthFromEnd(k){ + let listArray = []; + let currentNode = this.head; + while(currentNode){ + listArray.push(currentNode.data); + currentNode = currentNode.next; + } + if(k < 0){ + return 'k needs to be a postive integer'; + } + let kIndex = ((listArray.length - 1) - k); + if(kIndex < 0){ + return 'error'; + } else { + return listArray[kIndex]; + } + } + mergeLists(list1, list2){ + if(list1 === null || list2 === null){ + return 'Not valid Linked List'; + } + let array1 = list1.toString().split(','); + let array2 = list2.toString().split(','); + let final = new LinkedList; + if (array1.length - array2.length > 1 || array2.length - array1.length > 1){ + return 'Linked Lists are not close enough in length'; + } + if (array1.length >= array2.length) { + let answer = []; + for(let i = 0; i < array1.length; i++) { + answer.push([array1[i], array2[i]]); + answer = [].concat.apply([], answer); + } + answer.forEach(item=>{ + final.append(item); + }); + return final; + } + if (array1.length < array2.length){ + let answer = []; + for(let i = 0; i < array2.length+1; i++){ + answer.push([array2[i], array1[i]]); + answer = [].concat.apply([], answer); + } + answer.forEach(item=>{ + final.append(item); + }); + return final; + } + return null; + } + + +} + + +module.exports = LinkedList; \ No newline at end of file diff --git a/stacksAndQueues/node.js b/stacksAndQueues/node.js new file mode 100644 index 0000000..ae7d7e9 --- /dev/null +++ b/stacksAndQueues/node.js @@ -0,0 +1,10 @@ +'use strict'; + +class Node { + constructor(value){ + this.data = value; + this.next = null; + } +} + +module.exports = Node; \ No newline at end of file diff --git a/stacksAndQueues/readme.md b/stacksAndQueues/readme.md new file mode 100644 index 0000000..8543423 --- /dev/null +++ b/stacksAndQueues/readme.md @@ -0,0 +1,49 @@ +# Stacks and Queues + +Implement a Stack and a Queue Data Structure +[Travis](https://travis-ci.com/morgan-401-advanced-javascript/data-structures-and-algorithms/builds/134682110) + +## Challenge + +* Can successfully push onto a stack +* Can successfully push multiple values onto a stack +* Can successfully pop off the stack +* Can successfully empty a stack after multiple pops +* Can successfully peek the next item on the stack +* Can successfully instantiate an empty stack +* Can successfully enqueue into a queue +* Can successfully enqueue multiple values into a queue +* Can successfully dequeue out of a queue the expected value +* Can successfully peek into a queue, seeing the expected value +* Can successfully empty a queue after multiple dequeues +* Can successfully instantiate an empty queue + +## Approach & Efficiency +Stack: +* push O(1) we only manipulate the first item in the stack +* pop O(1) we only manipulate the first item in the stack +* peek O(1) we only manipulate the first item in the stack + +Queue: +* enqueue O(1) we only manipulate one item in the stack +* dequeue O(1) we only manipulate one item in the stack +* peek O(1) we only manipulate one item in the stack +## API +`class Stack { + constructor(){ + this.top = null; + } + push(value) + pop() + peek() +}` + +`class Queue { + constructor(){ + this.front = null; + this.rear = null; + } + enqueue(value) + dequeue() + peek() +}` diff --git a/stacksAndQueues/stacks-and-queues.js b/stacksAndQueues/stacks-and-queues.js new file mode 100644 index 0000000..53d7d8b --- /dev/null +++ b/stacksAndQueues/stacks-and-queues.js @@ -0,0 +1,78 @@ +'use strict'; +const Node = require('./node.js'); + +class Stack { + constructor(){ + this.top = null; + } + push(value){ + if(value !== null){ + let newItem = new Node(value); + if(this.top !== null){ + newItem.next = this.top; + this.top = newItem; + } else { + this.top = newItem; + } + + } else { + return 'bad value'; + } + } + pop(){ + if(this.top !== null){ + this.temp = this.top; + this.top = this.temp.next; + return this.temp.data; + } else { + return 'null'; + } + } + peek(){ + if(this.top !== null){ + return this.top.data; + }else{ + return 'no data!'; + } + + } +} + +class Queue { + constructor(){ + this.front = null; + this.rear = null; + } + enqueue(value){ + if(value !== null){ + let newItem = new Node(value); + if(this.rear === null){ + this.rear = newItem; + this.front = newItem; + }else{ + this.rear.next = newItem; + this.rear = newItem; + } + }else{ + return 'bad value'; + } + } + dequeue(){ + if(this.front !== null){ + this.temp = this.front; + this.front = this.temp.next; + return this.temp.data; + }else{ + return 'null'; + } + } + peek(){ + if(this.front !== null){ + return this.front.data; + }else{ + return 'empty queue'; + } + } +} + +module.exports = { Stack, Queue}; \ No newline at end of file diff --git a/tree/README.md b/tree/README.md new file mode 100644 index 0000000..7a8122f --- /dev/null +++ b/tree/README.md @@ -0,0 +1,15 @@ +# Trees + + + +## Challenge + + + +## Approach & Efficiency + + + +## API + +