Data Structures and Algorithms

Measuring Complexity of Pseudocode

An exercise: Find \(f(n), g(n)\) such that \(f(n) \ne O(g(n))\) and \(g(n) \ne O(f(n))\).

Answer: \(\sin(n)\) and \(\cos(n)\), since under the Big O definition there is no constant \(n_0\) for which one function is thereafter greater than the other.

Determining Logarithmic Runtime in a Program

Logarithmic behavior is typically in a program that divides the input size every step. This could be something like binary search, or an update condition in a for loop:

for (int i = 100; i > 0; i /= 2)

Complexity Analysis

  • Each step takes \(O(1)\) time
  • Goal: Find time based on \(n\)
  • Tools:
    • Find rate of growth as \(f(n)\)
    • Use Big-O notation to compare different growth rates

Complexity Cases

  • Best case: The input case of size \(n\) which will take the shortest amount of time. For example, in linear search, the element could be the first element in the array.
  • Worst case: The input case of size \(n\) which would take the most amount of steps. In linear search, this would mean checking every element until the end.
  • Average case: The average input case. This would be \(\frac{n}{2}\) in linear search.

Amortized Complexity

A special kind of worst-case complexity that considers how an algorithm performs over a large series of inputs. It is just the total cost of the operations divided by \(n\).

"If you use it a lot, it behaves as if it were ..."

Measuring runtime

On Unix, use /usr/bin/time. Call it like so:

/usr/bin/time [some command here]

Or, if you want to measure the amount of time a block of code takes, use <sys/time.h>:

#include <resource.h>
#include <sys/resource.h>
#include <sys/time.h>

int main() {
    struct rusage startu;
    struct rusage endu;

    getrusage(RUSAGE_SELF, &startu);
    // computations that you want to time
    getrusage(RUSAGE_SELF, %endu);
}

Pseudocode

Pseudocode is a special way to describe algorithms. It is a mixture of English and programming to communicate what an algorithm does in the simplest way.

procedure fizzbuzz
For i := 1 to 100 do
    set print_number to true;
    If i is divisible by 3 then
        print "Fizz";
        set print_number to false;
    If i is divisible by 5 then
        print "Buzz";
        set print_number to false;
    If print_number, print i;
    print a newline;
end

It is meant to be readable, and there is no single standard.