Hash functions:

If we have two different hash values then we know that their keys must be different. If we have two identical hash values then we don’t know anything, because collisions (different keys that hash to the same value) are possible.

Handling collisions:

The load factor \(\alpha\) of a hash table is the ratio of elements stored \(n\) to \(m\), the size of the table. With open addresses, the maximum load factor is 1.0.

Hash functions should be


Expression trees

Data structure for encoding the (recursive) structure of various kinds of expressions. (Each kind of expression will have its own expression tree type.) We build expression trees using inheritance: we have a base class for “all expressions of this type” and then subclasses for particular types of subexpressions. E.g., in arithmetic expressions, we have

We definitely need a subclass for the first four, and maybe a fifth for parentheses, depending on what we are doing. (We might even choose to split the different infix operators into different subclasses.)

Example: A ring is a mathematical structure consisting of a set of values a, b, c, etc. together with two operations:

and two identified elements

(Parentheses are also allowed.)

An expression tree structure for general rings would need:

A sketch of this would be something like

struct ring {}; // Base class

struct ring_elem : public ring { string e; };
struct ring_zero : public ring { };
struct ring_one  : public ring { };
struct ring_plus : public ring { ring* left; ring* right; };
struct ring_mult : public ring { ring* left; ring* right; };

(If I ask you to do this on a test, you don’t need to worry about constructors or methods.)