Over the last few years I've written notes on various computer science topics. For the most part these were written with the intent of teaching other students so parts may be informal and lack thorough explanation.
B-Trees are used to reduce the height of a tree as you add to it i.e. making sure the tree is not "spindly." They are self-balancing trees
B-Trees of order L=2 are 2-3 Trees and B-Trees of order L=3 are 2-3-4 Trees (2-4 Trees).
2-3 Trees have at most 2 elements per node and at most 3 children per node.
2-3-4 Trees have at most 3 elements per node and at most 4 children per node.
2-3 Tree:

2-3-4 Tree:

Note: you can have other types of elements in your B-Tree such as letters or arbitrary objects (so long as these objects can be ordered).
Algorithm for searching for an element of a 2-3 Tree:
- (Similar to searching in a BST)
- Look at each node and determine which child to continur your search in
- Repeat until element is found
Algorithm for
inserting an element into a 2-3 Tree:
- Insert element into the leaf node that it should be added to
- If node is not full
- Add that element to the node
- If leaf node is full
- Split the elements of the full node plus the new element into two child nodes with the median of the three elements acting as the parent
- If possible, add this element to the original parent node
- If not possible, continue this splitting process upwards
- If the process continues to the root node create a new node above the root
- Note: this is the only time where the height of the tree can be increased
Algorithm for
deleting an element from a 2-3 Tree:
- (There are a few different algorithms)
- (It's hard)
B-Tree Invariants (things that are always true):
- All leaf nodes are the same distance from the root
- If a non-leaf node contains n elements, it has n+1 children
- Every node (other than the root) is at least half full
- The root has at least two children as long as the height is 1
Time Complexity:
Searching for a node:
O(logn)
Insertion:
O(logn)
Deletion:
O(logn)
The Euclidean Minimum Spanning Tree of a set of points is the MST of points where edge weights are the Euclidean distances between the points defining the edge.
Naively you can compute the EMST by creating a complete graph the set of points where the edge weights are the Euclidean distances between those two points and then run Prim's or Kruskal's on the resulting graph.
Space Complexity: O(n^2)
Time Complexity is O(n^2)
A more efficient strategy is to note that the Delaunay Triangulation contains the EMST and an algorithm for caluculating the Deluanay Triangulation runs in O(nlogn). Simply run Prim's or Kruskal's on the Delaunay Triangulation. The resulting for computing the EMST run in O(nlogn).
When we define classes we can choose for them to have iter() and next() methods. This is important if we want to define objects that act like a list for example or, alternatively, you can think of it as giving an order to the elements in some container you define.
iter(iterable): return and iterator over the elements of an iterable value
next(iterator): return the next element in an iterator
How is an iterator different from a list?
Think of the iterable as a book and the iterator as a bookmark you can only use once.
Also, say you have a list l = [1, 2, 3] it wouldn’t make sense to call next(l). This doesn’t make sense; next from what? However if you turned l into an iterator l_iter = iter(l) then that’s telling us to start on the first element then subsequent calls to next(l_iter) will give us the next element after.
>>> l = [1, 2, 3]
>>> next(l)
error
>>> l_iter = iter(l)
>>> next(l_iter)
1
>>> next(l_iter)
2
When there are no elements left to go through you should raise a StopIteration exception.
Remember that once you go through an iterator you can’t go back. So, once you’ve iterated over everything that instance of the iterator is now basically useless.
Also, for loops implicitly call on iter and next.
SQL is an example of a declarative programming language. Statements do not describe computations directly, but instead describe the desired result of some computation.
A table has a fixed number of named and typed columns. Each row of a table represents a data record and has one value for each column. We can choose which columns to show, filter using a where clause, and sort with an order by clause using the following syntax:
select [columns] from [tables] where [condition] group by [group] order by [order] limit [limit];
Alternatively if you have individual data points you can create tables with this syntax as well:
select [val] as [type], ... union
select ...
When tables are joined, the resulting table contains a new row for each combination of rows in the input tables. If two tables are joined and the left table has m rows and the right table has n rows, then the joined table will have m · n rows. Joins are expressed in SQL by separating table names by commas in the from clause of a select statement.
SELECT b.Berkeley - a.Berkeley, b.Stanford - a.Stanford, a.Year, b.Year
FROM Football AS a, Football AS b WHERE a.Year < b.Year;
In order to perform SQL aggregation, we can group rows in our table by one or more attributes. Once we have groups, we can aggregate over the groups in our table and find things like:
- the maximum value (MAX),
- the minimum value (MIN),
- the number of rows in the group (COUNT),
- the average over all of the values (AVG),
and more! SELECT statements that use aggregation are usually marked by two things: an aggregate function (MAX, MIN, COUNT, AVG, etc.) and a GROUP BY clause. GROUP BY [column(s)] groups together rows with the same value in each column(s). In this section we will only use COUNT, which will count the number of rows in each group.
SELECT number, COUNT(*) AS count FROM students GROUP BY number ORDER BY count DESC LIMIT 10;
A table defined within a with clause may have a single recursive case that defines output rows in terms of other output rows. For example, the with clause below defines a table of integers from 5 to 15, of which the odd values are selected and squared.
sqlite> with
...> ints(n) as (
...> select 5 union
...> select n+1 from ints where n < 15)
...> select n, n*n from ints where n % 2 = 1;
5|25
7|49
9|81
11|121
13|169
15|225