# hparra/hgpa

Update/add all entries associated with "The Hector"

`WIP!`
hparra committed Feb 25, 2017
1 parent e99304d commit 2a439f02c6a8a5282b6b2152f312cbf219e25d4c
Showing with 434 additions and 82 deletions.
1. +92 −0 binary-heaps.md
2. +12 −0 binary-search.md
3. +33 −0 bitwise-math.md
4. +11 −0 dynamic-programming.md
5. +27 −0 hashing.md
6. +175 −0 hashtable.md
7. +0 −80 heaps.md
8. +26 −0 merge-sort.md
9. +15 −1 quick-sort.md
10. +28 −0 recursion.md
11. +15 −1 sorting.md
 @@ -0,0 +1,92 @@ Binary Heaps ============ _Read [heaps](heaps.md) first._ ## tl;dr Implementations: - python: [`heapq`](https://docs.python.org/2/library/heapq.html) - java: [`PriorityQueue`](https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html) - c++: [`priority_queue`](http://www.cplusplus.com/reference/queue/priority_queue/) - ruby: NONE ## Introduction A binary heap uses a complete binary tree. Recall that _complete binary trees_: - have each level filled, with possible exception of last level - when the last level is incomplete all nodes are filled from the left **Inserting into a binary heap**: 1. place new element in left most spot (n+1) 2. "Bubble Up": if and while (new) element dominates parent - swap them Swaps happen between levels, and a tree will have lg(n) levels. Since there are n items to be inserted, insertion will take `O(nlogn)`. **Extracting the dominator from a binary heap**: 1. remove dominating element from top 2. move last added element (bottom-right most leaf) into top 3. "Bubble Down": if and while that element does not dominate its children: - swap it with lesser of two children ### Implementing Binary Heaps Since a binary heap is a complete binary tree we can implement it using an array. Example: `2 7 8 1 5 9 3` pushed into min-heap as a tree: ``` 1 2 3 7 5 9 8 ``` But as an array looks like: `1,2,3,7,5,9,8,`. Notice this is equivalent to a breadth-first traversal. This image from Wikipedia explains best: ![Implicit Binary Tree](https://upload.wikimedia.org/wikipedia/commons/8/86/Binary_tree_in_array.svg) So for some zero-based index `i`: - left child = `2i + 1` - right child = `2i + 2` - parent = `floor((i-1) / 2)` _WARNING: Beware zero and one-based version of the above equations. Many references use one-based equations because the math/logic is cleaner, but programmers always use zero-based arrays._ Notice that `floor(n/2)` is the index of one or more the the middle items of the array: - `floor(n/2)` if n is odd - `floor(n/2)` and `floor(n/2) - 1` if n is even To insert: 1. append number to list 2. "Bubble Up": - `parent = heap[floor((i-1)/2)]` - if parent < number then swap them - Test your inserts - Test your removals Note: - cannot be efficiently searched because it is not a BST - we don't know any facts that will improve a linear search Heap Interface: - get the dominating element, e.g. `min` or `max` - `add` or `insert` an element - `remove` or `delete` an element We can store any binary tree in an array without pointers but: - array still requires empty spots for missing nodes - methods to save memory make it less flexible ## RESOURCES https://en.wikipedia.org/wiki/Binary_heap [8.4. heapq — Heap queue algorithm](https://docs.python.org/2/library/heapq.html).
 @@ -0,0 +1,12 @@ Binary Search ============= ## Concept Assuming you have a SORTED list: 1. look at middle item in list: - if item is what you're searching then you're done! - if item < search then repeat (1) with first half of list - if item > search then repeat (1) with second half of list It's that simple
 @@ -0,0 +1,33 @@ Bitwise Math ============ | x | y | x & y | x or y | x ^ y | | --- | --- | ----- | ----- | ----- | | 0 | 0 | 0 | 0 | 0 | | 0 | 1 | 0 | 1 | 1 | | 1 | 0 | 0 | 1 | 1 | | 1 | 1 | 1 | 1 | 0 | **XOR** | x | y | x ^ y | | --- | --- | ----- | | 0 | 0 | 0 | | 0 | 1 | 1 | | 1 | 0 | 1 | | 1 | 1 | 0 | Always forgetting XOR? - Recall _eXclusive OR_ - We want what is in each but not in both - In other words: - true when their different - false when they're the same Remember these facts regarding XOR: - `a ^ a = 0` - `a ^ !a = 1` Checkout http://bits.stephan-brumme.com/
 @@ -21,6 +21,17 @@ Three traditional examples: - binomial coefficients - coin change problem ## Techniques - optimal substructure - overlapping subproblems You always have to solve the subproblems first. There are two different approaches to do this: - top down (recursive + memoization) - bottom up ## Common Applications **Longest Common Substring**: Given a set of strings, find the longest substring common to all strings. This could also be solved with a suffix tree.
 @@ -0,0 +1,27 @@ Hashing ======= ## Applications Some popular hashes include: - md5 - sha1 Some languages have default methods to create an identifying hash for an object: - Python: [`__hash__(self)`](https://docs.python.org/2/reference/datamodel.html#object.__hash__) - Java: [`hashCode()`](http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#hashCode%28%29) Some languages have default functions to create a hash: - Ruby: [`hash()`](https://docs.ruby-lang.org/en/2.0.0/Object.html#method-i-hash) - Python: [`hash()`](https://docs.python.org/2/library/functions.html#hash) ## RESOURCES [Hash function](https://en.wikipedia.org/wiki/Hash_function) [Varnish Does Not Hash](http://www.varnish-cache.org/docs/trunk/phk/varnish_does_not_hash.html). Poul-Henning. 2012-01-03. "The way to avoid having hash-collisions is to not use a hash: Use a tree instead." [What happens when you mess with hashing in Python](http://www.asmeurer.com/blog/posts/what-happens-when-you-mess-with-hashing-in-python/).