Skip to content

aileenmwong/Big-O-102

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

title type duration creator competencies
Data Structures
lesson
2:30
name city
Ari Brenner
NY
Programming

Big-O 102: Data Structures and Beyond

Objectives

After this lesson, students will be able to:

  • Identify common data structures
    • Linked lists, Trees, Heaps, Tries, Graphs
  • Be familiar with their common methods
    • And be able to determine their run-times
  • Know use-cases for each data structure discussed

Preparation

Before this lesson, students should:

  • Have practice reading/writing pseudocode
  • Be familiar with Big-O and common run-times

Linked Lists

http://www.csegeek.com/csegeek/view/tutorials/algorithms/linked_list/linked_list.jpg

Linked lists are used to represent an ordered set. They are similar to arrays but do NOT live contiguously in memory.

We have a reference to the head (and possibly the tail). Each node has a reference (or pointer) to the next node.

In a doubly-linked-list each node also has a reference to the prev node.

We cannot get an element at a given index in constant time. We must iterate over the list.

We can however insert/remove an element to the head in constant time. This is not the case for an array. (Hence shift/unshift )

Common use-cases

Linked Lists are often used to represent Stacks and Queues.

Why might we prefer to use linked list to implement a stack or queue? Why not an array?

Discussion

Why would we choose to use a linked list over an array? What are the advantages and disadvantages?

Trees

A tree is a collection of nodes, where each node has some number of children. We cannot see every node at once, but we do have a pointer to the root node.

Leaf nodes are those that have no children.

Trees can be used to represent a family tree (where the old people are on top), or a file structure.

Traversal

We can traverse a tree using Depth first search or Breadth first search. More on this below.

Binary Search Trees

https://i.stack.imgur.com/36FkR.png

A binary tree is a tree such that every node has at most 2 children.

A binary search tree (BST) is one such that:

  • The value of every left child is less than that of its parent
  • The value of every right child is greater than that of its parent

This makes searching for elements in a BST very fast.

To insert into a BST, we compare the new val with the root value. If it is less than the root, we repeat the process for the left subtree. If it is greater than the root we repeat the process for the right subtree. We keep repeating this process until our node ends up on the bottom.

Look up how to remove a node if you are interested ;)

Traversal

Depth first search

Tree.instanceMethods.traverse(callback) :=
  left.traverse(callback) if hasLeftChild?
  callback(value)
  right.traverse(callback) if hasRightChild?

The above pseudocode is called in-order traversal. Check out pre-order and post-order as well.

Breadth first search

This is a little more complicated. Look it up if you are interested ;)

Discussion

How quickly (in Big-O) can we find an element in a BST with n elements?

How quickly can we find the min element? The max element?

Check out my Typescript and compiled Javascript implementations

AVL Trees

An AVL (named for its inventors) tree is a self-balancing binary search tree. You do not need to understand how these work but know that they exist.

Self-balancing means that whenever we insert or remove a node, we re-organize the rest of tree so that no node with 0 or 1 children hangs more than 1 level below another.

Discussion

Why would we want a self-balancing tree? Is it worth the implementation? Are the run-times different than a tree that is not self-balancing?

(Min) Heap

A Min Heap is binary tree such that the value of every node is less than the value of all of its children. Thus, the smallest value is always the root of the tree.

They are used when we want to keep track of the smallest element in a set.

You can probably guess what a Max Heap is

http://interactivepython.org/runestone/static/pythonds/_images/heapOrder.png

Reading

To get the min element we just look at the root. (Duh)

Inserting

To insert elements, we add a node to first available position (the bottom-left) and "bubble it up". This means we keep swapping it with its parent until the value of the node is no longer larger than the parent.

How do we know inserting in this way will always leave us with a Min Heap?