APIs and Elementary Implementations
Collections. Insert and delete item.
Stack, Queue, Randomized queue, Priority queue.
Priority queue applications
- Event-driven simulation. [customers in a line, colliding particles]
- Numerical computation. [reducing roundoff error]
- Data compression. [Huffman codes]
- Graph searching. [Dijkstra’s algorithm, Prim’s algorithm]
- Number theory. [sum of powers]
- Artificial intelligence. [A* search]
- Statistics. [maintain largest M values in a sequence]
- Operating systems. [load balancing, interrupt handling]
- Discrete optimization. [bin packing, scheduling]
- Spam filtering. [Bayesian spam filter]
Elementary PQ(MN), binary heap(NlogM)
insert, delmax, max
unordered array implementation
ordered array
Challenge. Implement all operations efficiently.
Binary Heaps
Binary tree. Empty or node with links to left and right binary trees.
Complete tree. Perfectly balanced, except for bottom level.
Binary heap. Array representation of a heap-ordered complete binary tree.
Heap-ordered binary tree.
- keys in nodes.
- Parent’s key no smaller than children’s keys.
Array representation.
- Indices start at 1.
- Take nodes in level order.
- No explicit links needed!
Proposition. Largest key is a[1], which is root of binary tree.
Proposition. Can use array indices to move through tree.
- parent of node is at k/2.
- Children of node at k are at 2k and 2k+1
Peter principle. Node promoted to level of incompetence.
private void swim(int k)
{
while (k > 1 && less(k/2, k))
{
exch(k, k/2);
k = k/2;
}
}
Insert. Add node at end, then swim it up.
public void insert(Key x)
{
pq[++N] = x;
swim(N);
}
Demotion in a heap
Scenario. Parent’s key becomes smaller than one (or both) of its children’s.
To eliminate the violation:
- Exchange key in parent with key in larger child.
Repeat until heap order restored.
private void sink(int k)
{
while (2*k <= N)
{
int j = 2*k;
if (j < N && less(j, j+1)) j++;
if (!less(k, j)) break;
exch(k, j);
k = j;
}
}
Power struggle. Better subordinate promoted.
Delete the maximum in a heap
Delete max. Exchange root with node at end, then sink it down.
public Key delMax()
{
Key max = pq[1];
exch(1, N--);
sink(1);
pq[N+1] = null;
return max;
}
public class MaxPQ<Key extends Comparable<Key>>
{
private Key[] pq;
private int N;
public MaxPQ(int capacity)
{
pq = (Key[]) new Comparable[capacity+1]; // ???
}
public boolean isEmpty()
{ return N == 0; }
public void insert(Key key)
public Key delMax()
{ /* see previous code */ }
private void swim(int k)
private void sink(int k)
{ /* see previous code */ }
private boolean less(int i, int j)
{
return pq[i].compareTo(pq[j]) < 0;
}
private void exch(int i, int j)
{
Key t = pq[i]; pq[i] = pq[j]; pq[j] = t;
}
}
d-ary heap
Fibonacci
Binary heap considerations
Immutability of keys.
- Assumption: client does not change keys while they’re on the PQ.
- Best practice: use immutable keys.
Underflow and overflow.
- Underflow: throw exception if deteting from empty PQ.
- Overflow: add no-arg constructor and use resizing array.
Minimum-oriented priority queue.
- Replace less() with greater().
- Implement greater().
Other operations.
- Remove an arbitrary item.
- Change the priority of an item.
Immutability: implementing in Java
- Data type. Set of values and operations on those values.
- Imumutable data type. Can’t change the data type value once created.
Immutable. String, Integer, Double, Color, Vector, Transaction, Point2D. // ???
Mutable. StringBuilder, Stack, Counter, Java array.
public final class Vector { // can't override instance methods
private final int N;
private final double[] data; // all instance variables private and final
public Vector(double[] data) { // defensive copy of mutable instance variables
this.N = data.length;
this.data = new double[N];
for (int i = 0; i < N; i++)
this.data[i] = data[i];
}
… // instance methods don't change instance variables
}
Advantages.
- Simplifies debugging.
- Safer in presence of hostile code.
- Simplifies concurrent programming.
- Safe to use as key in priority queue or symbol table.
Disadvantage. Must create new object for each data type value.
Heapsort
Basic plan for in-place sort.
- Create max-heap with all N keys.
- Repeatedly remove the maximum key.
Heap construction. Build max heap using bottom-up method.
for (int k = N/2; k >= 1; k--)
sink(a, k, N);
Sortdown. Repeatedlly delte the largest remaining item.
while (N > 1)
{
exch(a, 1, N--);
sink(a, 1, N);
}
public class Heap
{
public static void sort(Comparable[] a)
{
int N = a.length;
for (int k = N/2; k >= 1; k--)
sink(a, k, N);
while (N > 1)
{
exch(a, 1, N);
sink(a, 1, --N);
}
}
private static void sink(Comparable[] a, int k, int N)
{ /* as before */ }
private static boolean less(Comparable[] a, int i, int j)
{ /* as before */ }
private static void exch(Comparable[] a, int i, int j)
{ /* as before */ }
}
but convert from 1-based indexing to 0-base indexing
Heapsort: mathematical analysis
Proposition. Heap construction uses ≤ 2 N compares and exchanges.
Proposition. Heapsort uses ≤ 2 N lg N compares and exchanges
Significance. In-place sorting algorithm with N log N worst-case.
- Mergesort: no, linear extra space. // in-place merge possible, not practical
- Quicksort: no, quadratic time in worst case. // N log N worst-case quicksort possible, not practical
- Heapsort: yes!
Bottom line. Heapsort is optimal for both time and space, but:
- Inner loop longer than quicksort’s.
- Makes poor use of cache memory.
- Not stable.
Event-Driven Simulation
Goal. Simulate the motion of N moving particles that behave according to the laws of elastic collision.
Hard disc model.
- Moving particles interact via elastic collisions with each other and walls.
- Each particle is a disc with known position, velocity, mass, and radius.
- No other forces.
Significance. Relates macroscopic observables to microscopic dynamics.
- Maxwell-Boltzmann: distribution of speeds as a function of temperature.
- Einstein: explain Brownian motion of pollen grains.
Time-driven simulation. N bouncing balls in the unit square.
Event-driven simulation
Change state only when something happens.
- Between collisions, particles move in straight-line trajectories.
- Focus only on times when collisions occur.
- Maintain PQ of collision events, prioritized by time.
- Remove the min = get next collision.
Collision prediction. Given position, velocity, and radius of a particle, when will it collide next with a wall or another particle?
Collision resolution. If collision occurs, update colliding particle(s) according to laws of elastic collisions.
Particle-wall collision
Particle-particle collision prediction
Particle-particle collision resolution
还没理解。