Presented by Bianca Gandolfo

1

Cooking with

Data Structures & Algorithms

in

JavaScript

 

 

@BiancaGando

 

@BiancaGando

Who is Bianca? 

 

Bianca is an educator, engineer,

cofounder of Telegraph Academy,

and currently the Interim Managing Director of

Hack Reactor Remote Beta

 

If curious, read my bio.

 

 

 

 

 

@BiancaGando

 

Who is Bianca? 

 

Algos and DS Experience Timeline:

2013                 Inspired by an n-queens algorithm challenge

Always             Enjoyed the puzzle-solving aspect

2013                 Worked at Hack Reactor, Founded Algorithm Meet-up

Over the yrs  Studied lots of MOOCs and interviews

                                                  Courses under my belt: Harvard CS50, Princeton Algorithms I & II, MIT CS 6.006 & more

2015                 Founded Telegraph Academy

2016                 Started as Interim Managing Director of Remote Beta

2015-16            Created this course with Jeff Lee & Katrina Uychaco

 

@BiancaGando

 

Workshop Topics by Day

 

Day 0 - Recursion and Object-Oriented JS*

Day 1 - Time Complexity, Sorting

Day 2 - Trees & Searching Algorithms

Day 3 - Graphs & Paths

Day 4 - Hash Tables & Hashing

Day 5 - [Bonus] Advanced Applications & Optimizations 


Disclaimer: I will cover, at minimum, the above topics such that you have a working conceptual knowledge, but it is unlikely you will be able to finish the exercises in the allotted time for the live workshop. Also, I will have limited time to go over the solutions to the exercises. Annotated solution code will be provided in JavaScript.

 

*Important: ALL following lessons depend on mastering the Day 0 concepts.

 

@BiancaGando

 

Daily Class Schedule

 

Subject to Change without Notice

​​9:00-9:30      Morning Coffee & Intro

9:30-9:35      Snack Break

9:35-10:30    Intro to AM Recipe

10:30-11:30  Practice in Pairs

11:30-12:00  Taste Test

12:00 - 1:00  Lunch

1:00 - 1:30    Intro to PM Recipe

1:30 - 2:00    Practice in Pairs

2:00 - 2:30    Continuing with PM Recipe

2:30-3:30      Practice in Pairs

3:30-4:00      Dessert

 

@BiancaGando

 

What this class is

 

 

1. A practical introduction to data structures and algorithms in JavaScript

 

2. Carefully curated topics based on university-level CS courses and common technical interview questions.

 

3. A good starting point for anyone who wants to up their programming and interview game by mastering the fundamentals

 

5. Useless if you don't complete the exercises

1

@BiancaGando

 

 

1. Every data structure and algorithm ever invented

 

2. The only method of implementation or the best solution for every case

 

4. A math-heavy or theory course on the analysis of algorithms

 

5. The end-all study tool for your interview preparation

 

6. A smooth, friendly tour of Algos/DS - We are packing in a lot of content so be prepared to be challenged and for you to be left to answer some of your own questions.

 

What this class is not

 

@BiancaGando

 

Fad Diets

"Reading or watching a video about this concept means I know how to code it out." Sorry! It's not that easy.

 

"I'm going to look it up later." No you won't.

 

"My brain hurts. I am not smart!" Mine hurts too!

 

"Failing an interview means I'm a bad engineer because interviews are testing for my engineering ability." False. 

 

"That seems easy so I'm going to skip the exercises." -or-  

"I read the solutions and now I understand it." Not a good idea!

 

 

 

 

 

 

@BiancaGando

 

Text

@BiancaGando

Don't participate in the "fad diets"

 

Pair with someone else taking the course

 

Do the exercises without looking at the solutions

 

Be OK with failing and don't give up

 

Ask Questions

How to Succeed

Text

@BiancaGando

This can be tough at first, but helps a lot for interview prep.

 

Communicate deliberately and be specific.

 

One person gets to be the driver while the other navigates.

 

The driver types. The navigator talks through the code.

 

Use codeshare.io for remote pairing.

 

Be courteous. Have fun!

 

A Guide to Pair Programming

Text

@BiancaGando

 We will be using Slido to manage questions.

 

Step 1: Go to www.slido.com

Step 2: Enter this code #femasters

Step 3: Enter questions as they come up for you.

Step 4: Vote on other questions you also would like.

Note: Once you submit a question, you cannot delete or edit 

 

I will answer the most popular questions between topics.

 

Let's practice!

How to Ask Questions

Object-Oriented JavaScript:

Pseudoclassical

1

JavaScript is an object-oriented programming language, but it does not have a "formal" way of creating class constructors* like most languages, hence the name: pseudoclasses.

 

*Ok - maybe it does just in ES6

 

@BiancaGando

 
function Building(floors) {
  this.what = "building";
  this.floors = floors;

}
Building.prototype.countFloors = function() {
  console.log('I have',  this.floors, 'floors');
};

Recipe

 

Constructor

Properties

(per instance)

Defining a (pseudo)Class

Methods (for all instances)

function Building(floors) {
}

@BiancaGando

 

Cooking it

 

Using a (pseudo)Class

 
var yourHouse = new Building(2);

var theOffice = new Building(12);

yourHouse.countFloors();

theOffice.countFloors();

The results of the shared method depend on the unique instance values which are created at call-time inside each function's scope.

 

@BiancaGando

 
function Building(floors) {
  this.what = "building";
  this.floors = floors;

}
Building.prototype.countFloors = 
function() {
  console.log('I have',  
    this.floors, 'floors');
};

Things to Note

 

There are several methods of creating classes in JavaScript.

 

Pseudoclassical is the industry standard and is expected knowledge in an interview.

 

You may see elements of this style in your favorite JS framework.

 

@BiancaGando

 

More Things to Note

 

Subclassing and inheritance are not covered in this course.

 

For more in-depth information on classes and subclasses,

I recommend this blog

 

@BiancaGando

 

Exercise Time!

Create a unique constructor that makes a building of your choice using the pseudoclassical pattern.

Don't forget to add methods and practice creating instances.

@BiancaGando

Intro to

Data Structures
Stacks & Queues

 

@BiancaGando

 

Ingredients to Learn DS

 

1. Learn Data Structure Concept

    - Draw it

    - Create the API/operation methods

2. Build the Data Structure

    - Pseudocode the implementation

    - Code the data structure constructor

3. Utilize the Data Structure

    - Put your data structure to work!

    - Pair it with an algorithm if needed

4. Understand Data Structure

    - What is the time complexity? (coming soon)

    - How can you optimize?

 

@BiancaGando

 

Concept: Stacks

 

The Last item added Into the stack will be the First one taken Out of the stack.
 

 

(aka pushed onto)

(aka popped off)

"LIFO"

 

@BiancaGando

 

0

1

2

3

Diagram: Stacks

 

@BiancaGando

 
var makeEggs = function(style, n) {
    var completedEgg;
    if (style !== "boiled") {
        var crackedEggs = crackEggs(n);
        if (style !== "scrambled") {
            completedEgg = fryEgg(crackedEggs, style);
        } else {
            var preppedEggs = whipEggs(crackedEggs)
            completedEgg = fryEgg(preppedEggs)
        }
    }
    //... other procedures here
    return completedEgg;
}

makeEggs('scrambled', 3);
makeBacon('crispy', 2)
\

Call Stack

7
6
5
4
3
2
1
0

Interface: Stacks

 

1. Constructor Function

    - Storage 

2. Methods

    - push(value) //adds value to the front, returns size of stack

    - pop() //removes value from front, returns value

    - size() //returns size of stack as an integer

 

 

@BiancaGando

 

Interface: Stacks

 

1. Constructor Function

    - Storage 

  

2. Methods

    - push(value) 

    - pop() 

    - size() 

 

 

@BiancaGando

 
var Stack = function(){
    this.storage = "";
};

Stack.prototype.push = function(val){

};

Stack.prototype.pop = function(){

};

Stack.prototype.size = function(){

};

var myWeeklyMenu = new Stack();

myWeeklyMenu.push("RedBeans");

Text

@BiancaGando

Pseudocode: Stacks

Concept: Queues

The First item added Into the queue will be the First one taken Out of the queue.

(aka enqueued)

(aka dequeued)

@BiancaGando

 

"FIFO"

 

myQueue.enque(1)

myQueue.enque(2)

myQueue.deque()

myQueue.enque(3)

myQueue.enque(4)

myQueue.deque()

Diagram: Queues

@BiancaGando

 

Interface: Queues

 

1. Constructor Function

    - Storage 

2. Methods

    - enqueue(value) //adds value to the back, returns size

    - dequeue() //removes value from front, returns value

    - size() //returns size of queue as an integer

 

 

@BiancaGando

 

@BiancaGando

Pseudocode: Queues

Exercise Time!

@BiancaGando

Pancake Stacks

 

Browser History/Undo Button

JS Call stack

Stack Overflow

Email Inbox

 

Queues out the Door

 

JavaScript's Event Queue

Message Queueing (Buffer)

Ticket Sales (ticketmaster)

Popup Windows

 

IRL Uses

 

@BiancaGando

 

Recursion

 
var callMe = function() {
  callMe();
  callMe();
  callMe('anytime');
};

Recursion is simply when a function calls itself; however it doesn't stop there.

 

@BiancaGando

 

Why Recursion?

 

Recursive Functions

Recursive Algorithms

Recursive Data Structures

 

 
var callMe = function() {
  callMe();
  callMe();
  callMe("anytime");
};

@BiancaGando

 

Why Recursion?

 

Elegant solutions to keep your code D.R.Y.

 

Expected CS knowledge

 
var callMe = function() {
  callMe();
  callMe();
  callMe("anytime");
};

@BiancaGando

 

@BiancaGando

var callMe = function() {
  callMe();
  callMe();
  callMe('anytime');
};

WTHeck is this doing?

 
var callMe = function() {
  

  callMe('anytime');
};
var callMe = function() {
  return 'no more infinite loops!';

  callMe('anytime');
};
var tracker = 0;
var callMe = function() {
  tracker++
  if (tracker === 3) {
      return 'loops!';
  }
  callMe('anytime');
};
var tracker = 0;
var callMe = function() {
  tracker++
  if (tracker === 3) {
      return 'loops!';
  }
  return callMe('anytime');
};

Recipe

 
var callMyself = function() {

  if() {
    // base case
    return;
  } else {
    // recursive case
    callMyself();
  }
    
  return;
};
  1. Identify base case(s).
  2. Identify recursive case(s).
  3. Return where appropriate.
  4. Write procedures for each case that bring you closer to the base case(s).
 

@BiancaGando

 

Text

@BiancaGando

Looping

var loopNTimes = function(n) {
  console.log('n equals', n)  
  if (n <= 1) {
      return 'complete';
  }
  return loopNTimes(n-1);
};

loopNTimes(3);

Factorial w Loop

 
function computeFactorial(num) {
  var result = 1;

  for(var i = 2; i <= num; i++) {
    result *= i;
  }

  return result;
}
results *= 2;
results *= 3;
results *= 4;
results *= 5;

If we call computeFactorial(5), then the loop will run:

What pattern do you notice?

 

@BiancaGando

 

w/ Recursion

 
function computeFactorial(num) {
  if(num === 1) {
    return 1;
  } else {
    return num * computeFactorial(num - 1);
  }
}
5 * computeFactorial(4)
    4 * computeFactorial(3)
        3 * computeFactorial(2)
            2 * computeFactorial(1)
                1

If we call computeFactorial(5), then the recursion will run:

@BiancaGando

 
function logNumbers(start, end) {
  for(var i = start; i <= end; i++) {
    console.log(i);
  }
}

function logNumbersRecursively(start, end) {
  function recurse(i) {
    console.log(i);

    if(i < end) {
      recurse(i + 1);
    }
  }

  recurse(start);
}

Loop to Recursion

 

@BiancaGando

 

Recursion vs Loops

 

Recursion can always be implemented as a loop, but often, especially with certain DS it is much easier to use recursion.

 

Loops are more performant than recursion in JavaScript because every function call is added to the stack, state must be preserved, etc.

1

Tail-Call Optimization

 

In other languages, you can write your recursive functions in a way that the engine would recognize and optimize it by refactoring into a loop. The current version JavaScript does not implement TCO, but ES6 plans to implement this feature! Read more here and here 

 

@BiancaGando

 

Common Patterns for Recursion

 
  • Wrapper Functions
  • Passing Memos/Accumulators
 

@BiancaGando

 

Wrapper Function

 
function runRecursiveLoop(start, end) {
  function recurse(i) {
    console.log(i);
    if(i < end) {
      recurse(i + 1);
    }
  }

  recurse(start);
}

function runLoopAsMyself(i, end) {
  console.log(i);
  if(i < end) {
    runLoopAsMyself(i + 1, end);
  }
}

@BiancaGando

 

Memo, Accumilators

 
function joinElements(array, joinString) {

  function recurse(index, resultSoFar) {
    resultSoFar += array[index];

    if(index === array.length - 1) {
      return resultSoFar;
    } else {
      return recurse(index + 1, resultSoFar + joinString);
    }
  }

  return iterate(0, '');
}

@BiancaGando

 

Exercises!

(but first, a quick overview)

@BiancaGando

 

A Special Thanks to...


  

 

@BiancaGando

 

Katrina Uychaco

Exercises, Content and Solutions

 

Jeff Lee

Slides and Content

 

Recursion, OOJS, Stacks/Queues

By Bianca Gandolfo

Recursion, OOJS, Stacks/Queues

  • 10,481