This repo is my attempt to implement algorithms in Introduction to Algorithms by CLRS while I'm following MIT's Introduction to Algorithms course via their open course ware.
The purpose of writing notes, is to makes notes unnecessary. In the process of orginazing notes, I have understood the material.
Analyzing an algorithm is to predict the resources that the algorithm requires.
- most often, it's computational time we want to measure
It's traditional to describle the running time of a program as a function of the size of its input.
The running time of an algorithm on a particular input is the number of primitive operations or "steps" executed.
-
For now, we assume that to execute each line of our pseudocode (refers to the pseudocode in textbook, JS implementation here is a better reference), a constant amount of time is required.
-
Assume that each execution of the i th line takes time ci, where ci is a constant.
-
Calculate how many times the for loop and while loop will run.
-
The running time of the alogrithm is the sum of running time for each statement executed. A statement takes ci steps to execute and execute n times will contribute cin to the total running time.
- the goal of this step is to derive a function of n to express running time.
- this is the most importat step to find big O. Steps before this one is just a preparation for me to get the f(n). Everthing after this step relies on f(n) to do analysis.
-
Figure out the worst-case scenario - to sort an array in reverse sorted order.
-
Calculate the running time for worst-case scenario: a quadratic function of n.
-
It's rate of growth or order of growth, of the running time that really interests us. We drop the coefficient of leading term, and drop the non-leading terms of the formula. For large input n, these are relatively insignificant. Thus, Θ(n2).
Break the problem into several smaller subproblems that are similar to original problems, solve the problem recursively, then combine these solutions into a solution to the original problem.
My implementation follows the pseudocode in the textbook. console.log()
has been put into places that helps visually understand how the algorithm works.
The gist if insertion sort: While going through each item in the array, starting from the second item, compare current item's value to the previous item's value.
If previous item has larger value than current item, swap values. If not, do nothing.
For the case where the node to be deleted has both left and right child, we need to find a replacement node first.
This replacement node has these attributes:
- in the right sub-tree of the node to be deleted
- is the smallest node in the right sub-tree of the node to be deleted
Why does the replacement node need to have these attributes?
In order to maintain the BST structure:
- the replacement node has to be bigger or equal to any node in left sub-tree of node to be deleted,
- and smaller or equal to any node in right sub-tree of the node to be deleted.
Any node in the right sub-tree of NTBD(node to be deleted) is bigger or equal to any node in left sub-tree of NTBD. Now, we just need to find the smallest node in right sub-tree in NTBD.
What is a succssor of a given node? It the node has 1) smallest key, 2) greater than the given node.