This document introduces algorithms and their characteristics. It discusses the two phases of programming as problem solving and implementation. It covers understanding the problem, designing the algorithm, proving correctness, analyzing complexity, and coding the algorithm. Common algorithm design techniques like divide-and-conquer, greedy methods, and dynamic programming are presented. The document also discusses representing algorithms in pseudocode and natural language, and analyzing worst-case, average-case, and best-case complexity.