DESIGN AND ANALYSIS OF ALGORITHMS · UNIT 1

Understand the steps.
Measure the work.

Algorithmic problem solving, efficiency and orders of growth — with detailed notes and examples you can explore.

Start learningExplore an animation
Definitions preserved8 interactive explanations6 runnable Python examples12 written answersMobile friendly
Your supplied definitions, with more room to understand.

Source quotations retain their wording and identify the PDF page. Added explanations, worked traces and explicit corrections help you apply the ideas. Animations start only when you choose Play; use the step controls at your own pace.

DAA · UNIT 1 · 01

What is an algorithm?

SOURCE DEFINITION · PDF PAGE 1

Algorithm

It is a finite steps to solve a problem.

SOURCE DEFINITION · PDF PAGE 1

Algorithm (alternative definition)

An algorithm is a step-by-step procedure or set of well-defined instructions for solving a specific problem or performing a particular task.

Added explanation

An algorithm describes a method; a program implements that method in a language. A useful specification tells us the legal inputs, the required output and the steps that connect them. For example, “find the largest number” needs a nonempty list and must return a value at least as large as every element.

SOURCE DEFINITION · PDF PAGE 1

Well-defined

Algorithms have precise, unambiguous instructions that define how to perform a task. Each steps must be clear and understandable.

SOURCE DEFINITION · PDF PAGE 1

Finiteness

An algorithm must eventually terminate after a finite number of steps.

SOURCE DEFINITION · PDF PAGE 2

Effectiveness

Algorithms are practical and can be implemented using a finite amount of time and memory.

SOURCE DEFINITION · PDF PAGE 2

Input

Algorithms take input values as their starting point and produce output based on these inputs.

SOURCE DEFINITION · PDF PAGE 2

Output

Algorithms should generate at least one output or it may be more output.

PropertyExample: add two integers
Unambiguous stepsRead a, read b, compute a + b, display the result.
Finite executionFour main actions, followed by termination.
Effective operationsReading, arithmetic addition and displaying are executable operations.
InputTwo integers, a and b, within the chosen representation.
OutputTheir sum. An algorithm may take zero external inputs in other problems.

A counterexample: “Keep trying until it works” lacks a precise step and a termination condition. It is not a sufficient algorithm specification.

DAA · UNIT 1 · 02

From a problem to a correct program.

The supplied notes show six connected stages. Correctness checks and efficiency analysis can send us back to our decisions or design.

EXPLORE THE ALGORITHM

Six stages, one maximum-finding problem

Follow a single example through specification, design, proof, analysis and testing.

Enable JavaScript to explore the animation. The worked examples below remain available.

StageWhat you should write or check
UnderstandSpecify inputs, outputs, constraints and exceptional cases. Decide whether a known problem-solving method applies.
DecideChoose sequential or parallel execution, exact or approximate output, and a design strategy.
DesignExpress the method precisely using pseudocode, a flowchart or clear steps.
ProveShow that every legal input produces the required result and that the procedure terminates.
AnalyzeCount time-consuming operations and extra storage as functions of input size.
Implement and testTranslate into code, test ordinary and boundary cases, and revise the design when needed.
Maximum(A[0…n−1])  // n ≥ 1
    max ← A[0]
    for i ← 1 to n−1
        if A[i] > max
            max ← A[i]
    return max

Worked trace: [7, 2, 9, 4] → start max = 7 → compare 2 (keep 7) → compare 9 (update to 9) → compare 4 (keep 9). The answer is 9 after three comparisons.

Correctness invariant: after each iteration, max is the largest element in the inspected prefix. It holds initially for the first element, is preserved by the update, and gives the required maximum when the entire array has been inspected. A finite loop over n−1 remaining elements establishes termination.

DAA · UNIT 1 · 03

Make the assumptions explicit.

SOURCE DEFINITION · PDF PAGE 3

Sequential algorithms

In Random-access Machine, instructions are executed one after another. Algorithms designed to be executed on these machines are called sequential algorithms.

SOURCE DEFINITION · PDF PAGE 3

Parallel algorithms

In some newer computers, operations are executed concurrently, i.e. in parallel. Algorithms that take advantage of this capability are called parallel algorithms

SOURCE DEFINITION · PDF PAGE 4

Exact algorithm

An algorithm used to solve the problem exactly and produce correct result is called an exact algorithm

SOURCE DEFINITION · PDF PAGE 4

Approximation algorithm

If the problem is so complex and able to get exact solution, then we have to choose an algorithm called approximation algorithm.

Added explanation

The approximation sentence is preserved exactly from the PDF, including its wording “and able to get exact solution.” In algorithm design, an approximation method seeks a sufficiently good solution when finding an exact optimum is impractical. A stated quality guarantee matters; an approximate answer is not automatically correct for a task that requires an exact result.

DecisionExampleConsequence
Sequential or parallelA single processor scans a list; several workers may inspect different segments.Parallel work has communication and coordination costs.
Exact or approximateExact shortest route versus an approximate tour visiting many cities.State whether the task permits an approximate result and what quality is required.
Input assumptionsBinary search requires sorted data; sequential search does not.An algorithm can fail when its preconditions do not hold.
RepresentationAn array allows indexed access; a linked list does not provide constant-time indexing.Time analysis depends on the data representation and model.

DAA · UNIT 1 · 04

Describe the steps before coding.

SOURCE DEFINITION · PDF PAGE 5

Natural language

It is very simple and easy to specify an algorithm using natural language.

SOURCE DEFINITION · PDF PAGE 6

Psuedo code

Psuedo code is a mixture of a natural language constructs.

SOURCE DEFINITION · PDF PAGE 6

Flowchart

Flowchart is a graphical representation of an algorithm.

SOURCE DEFINITION · PDF PAGE 6

Flowchart (description)

It is a method of expressing an algorithm by a collection of connected geometric shapes containing descriptions of the algorithm's steps.

Added explanation

Pseudocode combines ordinary explanation with structured operations such as assignment, selection and iteration. The source spelling “Psuedo code” is retained in the quotation. The symbol ← denotes assignment; // starts a comment in the examples below. Unlike compiled code, pseudocode does not depend on one programming-language grammar.

Flowchart shapeMeaning
Oval / rounded terminalStart or End
ParallelogramRead input or display output
RectangleProcessing or calculation
DiamondDecision with labelled outcomes such as Yes and No
ArrowDirection of control flow

EXPLORE THE ALGORITHM

Watch the addition flowchart

Change either input, then advance one step at a time.

Enable JavaScript to explore the animation. The worked examples below remain available.

Sum(a, b)
    c ← a + b
    return c

Natural-language steps: read the first number; read the second number; add them and store the sum; display the sum. For a = 7 and b = 5, the output is 12. The selected basic operation, addition, executes once.

Add two numbers: one basic additionmain.py
a, b = map(int, input().split())
print("Sum =", a + b)
print("Additions =", 1)
EXPECTED OUTPUTSum = 12 Additions = 1

Try this program

DAA · UNIT 1 · 05

Choose a strategy that fits the problem.

SOURCE DEFINITION · PDF PAGE 4

Algorithmic strategy

Algorithmic strategy are a general approach by which many problems can be solved algorithmically

StrategyHow it worksExample and limitation
Brute forceUse a direct method or examine candidates systematically.Sequential search examines elements one by one. Simple and reliable, but checking all candidate subsets or permutations may be expensive.
Divide and conquerSplit into smaller subproblems, solve them, and combine their results.Merge sort divides the array and merges sorted halves. Typical array implementation uses Θ(n log n) time and Θ(n) auxiliary storage.
GreedyMake a locally preferred choice at each stage.Choose the earliest-finishing compatible interval for maximum-cardinality interval scheduling. Its correctness requires a proof; greedy is not valid for every optimization problem.
Dynamic programmingStore solutions to overlapping subproblems and reuse them.Compute Fibonacci values in a table instead of repeatedly recalculating them. Memoization or tabulation can save time while using storage.

One problem, several possible approaches

To find a key in an unsorted array, a direct scan is a suitable baseline. If the array is already sorted and supports indexed access, binary search can repeatedly reduce the remaining interval. If many searches are required, an index or hash table may justify preprocessing and additional memory. Include that preparation cost in the comparison.

Why a greedy choice needs proof

For coins {1, 3, 4} and amount 6, taking the largest coin first gives 4 + 1 + 1 (three coins). The optimum is 3 + 3 (two coins). A locally attractive choice can miss the global optimum.

Dynamic programming avoids repeated work

Naive recursive F(5) requests F(3) more than once. A table computes F(0) = 0, F(1) = 1, then F(2) = 1, F(3) = 2, F(4) = 3, F(5) = 5 once each. Under a unit-cost arithmetic model, tabulation takes Θ(n) time; retaining only the previous two values reduces extra storage to Θ(1). The size of large Fibonacci integers adds a separate bit-cost concern.

DAA · UNIT 1 · 06

Recognize a limitation. Measure an improvement.

Limitation in the notesReasonPossible improvement
High time complexityExhaustive candidate enumeration or repeated calculation.Change the strategy, store reusable results, or exploit valid input structure.
High space complexityLarge tables, copied data or deep recursion.Use rolling states, an in-place approach when valid, or iterative control.
Unsuitable input assumptionsA method expects sorted data or a restricted data model.Validate the assumption or select an algorithm that handles the actual inputs.
Complex implementationAdvanced methods introduce many dependent cases.Simplify the specification, document invariants and test systematically.
Lack of adaptabilityRequirements or data distributions change.Reevaluate the model, data structure and algorithm against new constraints.

The source suggests reducing time and space, selecting suitable data structures such as hashes, heaps, graphs and tries, simplifying logic, choosing a better design paradigm, and testing with dry runs. These are choices to justify for the specific problem; each has costs.

EXPLORE THE ALGORITHM

Improve the sum of 1 through n

Compare a loop with a formula that uses the special structure of this sequence.

Enable JavaScript to explore the animation. The worked examples below remain available.

LoopSum(n)
    sum ← 0
    for i ← 1 to n
        sum ← sum + i
    return sum

FormulaSum(n)
    return n × (n + 1) / 2

Worked example: n = 5 gives 1 + 2 + 3 + 4 + 5 = 15. The formula 5 × 6 / 2 also gives 15. The loop performs five additions; the formula uses a constant number of arithmetic operations. This shortcut applies to consecutive integers 1…n, not an arbitrary array of five values.

Constant factor versus growth class: reducing 3n² + 2n + 7 operations to n² improves the count, but both have Θ(n²) growth. Replacing the consecutive-sum loop with the formula changes Θ(n) to Θ(1) in this unit-cost model. Fixed-width overflow and the cost of large-integer arithmetic must still be considered.

Loop versus formula: sum 1 through nmain.py
n = int(input())
if n < 0:
    raise ValueError("n must be nonnegative")
total = 0
for i in range(1, n + 1):
    total += i
print("Loop sum =", total)
print("Formula sum =", n * (n + 1) // 2)
print("Loop additions =", n)
EXPECTED OUTPUTLoop sum = 15 Formula sum = 15 Loop additions = 5

Try this program

DAA · UNIT 1 · 07

State what n means and what you count.

SOURCE DEFINITION · PDF PAGE 8

Time efficiency

how fast the algorithm runs.

SOURCE DEFINITION · PDF PAGE 8

Space efficiency

how much extra memory it uses.

SOURCE DEFINITION · PDF PAGE 14

Input size

An algorithm's efficiency is defined as a function of some parameter 'n' indicating the algorithm's input size.

SOURCE DEFINITION · PDF PAGE 15

Basic operation

It is the most significant operation in an algorithm that contributes the most to its running time.

Efficiency analysis relates resource use to input size. State five things: the input-size parameter, computation model, selected basic operation, case being analyzed and resulting count or growth class.

ProblemInput-size parameterBasic operation
Search an arrayn = number of array elementsCompare an element with the key
Multiply two square matricesn = side length; each matrix contains n² entriesMultiply-and-add for an output entry
Process textn = number of charactersInspect one character
Integer problemOften b = number of bits in the integerArithmetic or bit operations, depending on the model

A numeric value N takes approximately ⌊log₂ N⌋ + 1 bits when N ≥ 1. A loop up to the numeric value N is not linear in its bit-length b. Choose the size parameter before labelling growth.

Why clock time alone is insufficient

Seconds and milliseconds depend on CPU, compiler, implementation quality and operating conditions. Counting operations provides a machine-independent model. If C(n) is the count and t is an approximate cost per operation, T(n) ≈ tC(n). The source highlights basic operations in inner loops, such as key comparisons. Not every problem has the same basic operation.

Time and extra space are separate

Scanning n elements can take Θ(n) time while keeping only a constant number of extra variables. An algorithm that stores an n-entry helper table uses Θ(n) additional space. Report auxiliary space separately from memory already occupied by the input; recursion stack frames count as extra storage.

DAA · UNIT 1 · 09

Keep input size fixed. Change the input.

SOURCE DEFINITION · PDF PAGE 19

Worst-case efficiency

Worst-case efficiency of an algorithm is its efficiency for the worst-case input of size n.

SOURCE DEFINITION · PDF PAGE 19

Best-case efficiency

Best-case efficiency of an algorithm is its efficiency for the best case input size n

SOURCE DEFINITION · PDF PAGE 19

Average-case efficiency

Average-case efficiency lies b/w best-case and worst-case.

Added explanation

Best and worst cases are the minimum and maximum operation counts over legal inputs of the same size n. Average-case efficiency is an expected count under a specified input distribution. It is not generally obtained by taking the midpoint of the best and worst counts.

Sequential search, n ≥ 1Input conditionExact comparisonsTight growth
Best caseFirst element matchesCbest(n) = 1Θ(1)
Worst caseFirst match is last, or key is absentCworst(n) = nΘ(n)
Average, successful uniform positionEach of the n first-match positions is equally likelyCavg(n) = (n+1)/2Θ(n)
Average with success probability pUniform first-match position conditional on successp(n+1)/2 + n(1−p)Θ(n), for this model

For n = 8: the best count is 1 and the worst count is 8. If every successful first-match position is equally likely and the key is always present, the average is (1 + 2 + … + 8)/8 = 4.5. A single execution still performs an integer number of comparisons.

DAA · UNIT 1 · 10

Weight each possible outcome.

EXPLORE THE ALGORITHM

Build the expected comparison count

Assumption: on success, the first matching position is uniformly distributed. Failure requires inspecting all n values.

Enable JavaScript to explore the animation. The worked examples below remain available.

Probability of first match at position i = p/n
Comparisons for that outcome = i
Probability of failure = 1 − p
Comparisons on failure = n

Cavg(n) = (p/n) Σ(i = 1…n) i + n(1−p)
        = p(n+1)/2 + n(1−p)
n = 8Expected countExplanation
p = 14.5Key always present; successful positions are uniform.
p = 0.56.250.5 × 4.5 + 0.5 × 8.
p = 08Key always absent.

If positions are not equally likely, replace p/n with their actual probabilities and sum probability × cost for each outcome. Duplicates also affect the distribution of the first matching position. An average claim without these assumptions is incomplete.

DAA · UNIT 1 · 11

Watch growth change with input size.

SOURCE DEFINITION · PDF PAGE 16

Order of growth

The order of growth describes how the running time increases as the input size 'n' grows.

Growth classModel functionTypical source of workEffect of doubling n
Logarithmiclog₂ nRepeatedly halve the remaining search interval.Adds 1 to log₂ n.
LinearnInspect every element once.Multiplies work by 2.
Linearithmicn log₂ nMerge sort levels each process Θ(n) elements.Slightly more than doubles.
Polynomial (fixed degree)nᵏ; e.g. n², n³Nested loops with a fixed number of levels.Multiplies by 2ᵏ.
Exponential2ⁿEnumerate all subsets of n distinct elements.Squares 2ⁿ when n is doubled.
Factorialn!Enumerate permutations of n distinct objects.Grows extremely quickly; (2n)!/n! is a product of n factors.

EXPLORE THE ALGORITHM

Compare seven growth functions

Actual numeric values are shown. Bar lengths use a labelled logarithmic visual scale so factorial values fit on screen.

Enable JavaScript to explore the animation. The worked examples below remain available.

nlog₂ nnn²2ⁿn!
424161624
8386425640,320
10≈ 3.322101001,0243,628,800
Added explanation

PDF page 17 places √n before log n in its growth-order line. That source line is: 1 < loglog n < √n < log n < n < n² < n³ < nᵏ < 2ⁿ < n!. For sufficiently large n, logarithmic growth is slower than √n. A corrected eventual order is 1, log log n, log n, √n, n, n log n, n², n³, 2ⁿ, n!. For any fixed degree k, nᵏ eventually grows more slowly than 2ⁿ. The order at very small n can differ.

The source table lists quicksort with n log n. Its average time is Θ(n log n) under suitable pivot/input assumptions, while its worst case is Θ(n²). Merge sort has Θ(n log n) worst-case time in the usual comparison model. The Tower of Hanoi needs exactly 2ⁿ − 1 moves, giving Θ(2ⁿ) growth.

DAA · UNIT 1 · 12

Separate an exact count from a growth class.

An exact expression such as 3n² + 2n + 7 counts selected operations in a model. Asymptotic notation describes how that expression behaves for sufficiently large n.

NotationAdded definitionExample
O(g(n))An asymptotic upper bound: f(n) ≤ c g(n) for some c > 0 and all n ≥ n₀.3n² + 2n + 7 is O(n²).
Ω(g(n))An asymptotic lower bound: f(n) ≥ c g(n) for some c > 0 and all n ≥ n₀.3n² + 2n + 7 is Ω(n²).
Θ(g(n))A tight asymptotic bound: positive constant multiples of g(n) bound f(n) from below and above eventually.3n² + 2n + 7 is Θ(n²).

These definitions are added explanations, not quotations from the supplied PDF. For n ≥ 1, 3n² ≤ 3n² + 2n + 7 ≤ 12n², demonstrating a tight quadratic bound. Constants and lower-order terms do not change this class.

Case and notation are different ideas: “worst case” specifies which inputs are considered; O or Θ specifies a bound on the resulting cost function. O does not inherently mean worst case. A best-case function can also have an asymptotic bound.

Sequential blocks: n + n² operations have Θ(n²) growth. Nested blocks: if each of n outer iterations performs n inner operations, the total is n × n = n². Do not multiply counts just because two loops appear in the same program.

DAA · UNIT 1 · 13

Derive the count from the loop bounds.

EXPLORE THE ALGORITHM

Count each execution of a loop body

Green cells have executed; the blue cell is the current operation. Faded triangular cells are outside the loop bounds.

Enable JavaScript to explore the animation. The worked examples below remain available.

Single loop:               Square nested loops:
for i ← 1 to n             for i ← 1 to n
    basic operation            for j ← 1 to n
                                   basic operation

Triangular nested loops:   Repeated halving:
for i ← 1 to n             value ← n
    for j ← 1 to i         while value > 1
        basic operation       value ← floor(value / 2)
PatternExact body countTight growthn = 4
SinglenΘ(n)4
Squaren × nΘ(n²)16
TriangularΣi = n(n+1)/2Θ(n²)10
Integer halving⌊log₂ n⌋, n ≥ 1Θ(log n) as n grows2

Count the chosen body operation first; loop-condition checks and increments are additional operations. The source programs deliberately print body counts. At n = 1, the halving loop performs zero divisions. The triangular loop saves about half the body work of the square loop for large n, while both remain quadratic.

Count linear, square, triangular and halving loopsmain.py
n = int(input())
if not 1 <= n <= 1000:
    raise ValueError("Choose n from 1 to 1000")
linear = square = triangular = halving = 0
for i in range(n):
    linear += 1
for i in range(n):
    for j in range(n):
        square += 1
for i in range(n):
    for j in range(i + 1):
        triangular += 1
i = n
while i > 1:
    halving += 1
    i //= 2
print("Linear =", linear)
print("Square =", square)
print("Triangular =", triangular)
print("Halving =", halving)
EXPECTED OUTPUTLinear = 5 Square = 25 Triangular = 15 Halving = 2

Try this program

DAA · UNIT 1 · 14

Preserve the GCD. Reduce the numbers.

SOURCE DEFINITION · PDF PAGE 20

Euclid's algorithm

Euclid's algorithm is a simple and efficient method for finding the greatest common divisor GCD of two numbers.

Euclid(a, b)  // positive integers
    while b ≠ 0
        r ← a mod b
        a ← b
        b ← r
    return a

EXPLORE THE ALGORITHM

Trace Euclid’s remainder steps

The PDF example is 48 and 18. Also try 54 and 24, 13 and 8, or 18 and 48.

Enable JavaScript to explore the animation. The worked examples below remain available.

StepDivisionNext pair
148 = 2 × 18 + 12(18, 12)
218 = 1 × 12 + 6(12, 6)
312 = 2 × 6 + 0(6, 0) → GCD = 6
Added explanation

Page 20 describes reducing the pair to (b, a mod b), but its displayed identity writes GCD(a, a % b). The correct invariant used in the runnable example is GCD(a,b) = GCD(b,a mod b). This clarification is separate from the preserved definition.

Why it works

Write a = qb + r. A common divisor of a and b divides a − qb = r. Conversely, a common divisor of b and r divides qb + r = a. Both pairs therefore have the same common divisors and the same greatest common divisor. When b becomes 0, GCD(a,0) = a.

Why it terminates and how to analyze it

Every nonzero remainder satisfies 0 ≤ r < b. The divisor decreases until a zero remainder appears. Count one remainder operation per iteration. For positive integers, the number of iterations is O(log min(a,b)) as the smaller input grows, with a constant initial allowance. This is a count of arithmetic steps; it does not assert that remainder operations on arbitrarily large integers cost constant time. Consecutive Fibonacci numbers produce many Euclidean steps.

Euclid's GCD and remainder countmain.py
a, b = map(int, input().split())
if a < 0 or b < 0 or (a == 0 and b == 0):
    raise ValueError("Use nonnegative inputs, not both zero")
remainders = 0
while b:
    a, b = b, a % b
    remainders += 1
print("GCD =", a)
print("Remainders =", remainders)
EXPECTED OUTPUTGCD = 6 Remainders = 3

Try this program

DAA · UNIT 1 · 15

Turn the trace into a real Python program.

Choose an example and load it into the embedded Python interpreter. Select I/O inside the compiler, check the sample STDIN, and press Run. Change the input or edit the source to explore a different case.

Sample input (STDIN)

3 7 11 16 22 29 35 42
42

Expected output

Index = 7
Comparisons = 8

Load the compiler when you’re ready to practise.

Your Python workspace

Edit real Python code and see real compiler output.

Compiler provided by OneCompiler. Opening the editor connects to that service; code and input you run are processed there. If the embed is unavailable, open the Python playground in a new tab and paste the source below.

View / copy the selected source
def sequential_search(values, key):
    comparisons = 0
    for i in range(len(values)):
        comparisons += 1
        if values[i] == key:
            return i, comparisons
    return -1, comparisons

values = list(map(int, input().split()))
key = int(input())
index, comparisons = sequential_search(values, key)
print("Index =", index)
print("Comparisons =", comparisons)

All six programs use Python 3. Search input is one line of space-separated values, then the key on the next line. Addition and GCD read two integers on one line. Loop and summation examples read n. Python integers grow as needed: operation-count analysis here uses a unit-cost arithmetic model, while large-number arithmetic has additional bit costs. Copy a program to your own Python interpreter if you prefer.

DAA · UNIT 1 · 16

Revise. Explain. Check your understanding.

These model answers are added study material. Use the source definitions above when your question asks for the wording of a definition.

Explain the characteristics of an algorithm.

An algorithm uses precise and unambiguous instructions, terminates after finitely many steps, and uses operations that can actually be carried out. Its input and output must be specified. For adding two integers, the inputs are a and b, the basic calculation is a + b, and the output is their sum. Each step is explicit and the procedure terminates.

Explain the fundamentals of algorithmic problem solving.

Understand the problem and its legal inputs and outputs. Decide the computational model, whether an exact or approximate solution is suitable, and the design strategy. Specify the algorithm using natural language, pseudocode or a flowchart. Prove correctness, analyze time and extra space, and implement and test. If analysis shows the approach is unsuitable, revisit the decisions and design.

Describe four algorithm design strategies with examples.

Brute force checks candidates directly, as in sequential search. Divide and conquer solves smaller subproblems and combines their answers, as in merge sort. Greedy methods choose a locally preferred option, as in interval scheduling by earliest finishing time. Dynamic programming stores answers to overlapping subproblems, as in a table of Fibonacci values. A strategy needs a correctness argument; a locally attractive choice is not automatically globally optimal.

What are algorithm limitations and how can they be improved?

Time growth, extra memory, restrictive input assumptions, difficult implementation and changing requirements can limit an algorithm. Improve it by avoiding repeated work, choosing a suitable data structure or design strategy, simplifying logic, and testing all relevant cases. Compare the same problem and assumptions. Some improvements trade memory for time; no single strategy is best for every problem.

Explain the analysis framework.

State input size n; identify the computational model and basic operation; count that operation for inputs of size n; specify the best, worst or average case; and express the order of growth. Example: for sequential search, n is the number of elements and the basic operation is comparing an element with the key. The counts are 1 in the best case and n in the worst case for n >= 1.

Why count basic operations instead of only measuring seconds?

A clock measurement changes with processor, compiler, program quality and operating conditions. Counting a chosen operation gives a model that can be compared across machines. If C(n) counts operations and one operation costs approximately t, then T(n) is approximately t times C(n). Real measurements remain useful, but they answer a different question from a growth analysis.

Analyze the best and worst cases of sequential search.

The best case occurs when the first element matches, so Cbest(n) = 1 and the nonempty-input best-case time is Theta(1). The worst case occurs when the last element is the first match or the key is absent, so Cworst(n) = n and worst-case time is Theta(n). Both refer to the same size n, not to a small versus a large list.

Derive the average-case count for sequential search.

Let success probability be p, and suppose the first matching position is uniform among the n positions conditional on success. Each successful position then has probability p/n and needs 1 through n comparisons. Failure has probability 1-p and needs n comparisons. Hence Cavg(n) = (p/n)(1 + 2 + ... + n) + n(1-p) = p(n+1)/2 + n(1-p). For p = 1 this is (n+1)/2. This is an expectation under stated assumptions, not a count for every individual run.

Explain logarithmic, linear, polynomial, exponential and factorial growth.

Repeatedly reducing the remaining work by a fixed factor leads to logarithmic growth, as with binary search on an already sorted random-access array. Scanning all elements is linear. Fixed-degree powers such as n squared and n cubed are polynomial. Examining all subsets yields 2 to the power n possibilities; examining all permutations of n distinct objects yields n factorial possibilities. For sufficiently large n, fixed-degree polynomial functions grow more slowly than fixed-base exponentials, which grow more slowly than factorials.

Analyze a single loop and nested loops.

A loop whose body executes n times performs n selected basic operations. Two loops that each run n times execute an inner operation n squared times. If the inner loop instead runs i times for outer values i = 1 through n, the exact count is 1 + 2 + ... + n = n(n+1)/2. Both nested examples have quadratic tight growth although their exact counts differ.

Explain Euclid’s algorithm and its correctness.

For positive a and b, repeatedly compute r = a mod b and replace (a,b) with (b,r) until b = 0. Return a. A common divisor of a and b divides a-qb = r, and a common divisor of b and r divides qb+r = a. Thus the set of common divisors is preserved. Each nonzero remainder is smaller than the previous divisor, so the process terminates. For 48 and 18, the remainders are 12, 6 and 0, giving GCD 6.

Can a constant-factor improvement change the growth class?

Replacing 3n squared + 2n + 7 operations by n squared operations reduces work but both counts have quadratic growth. Replacing a linear loop for the sum 1 through n with n(n+1)/2 changes the unit-cost arithmetic calculation from Theta(n) to Theta(1), provided the problem is summing that consecutive sequence, not summing arbitrary input values. Integer bit complexity and overflow must be considered outside this bounded learning model.

Check the key ideas

1. Which characteristic guarantees termination?
2. For searching an array, what does n normally denote?
3. For sequential search, what operation are we counting?
4. What is the best-case comparison count for a nonempty sequential search?
5. If the key is absent from a list of size n, how many key comparisons does sequential search make?
6. If every successful position is equally likely and p = 1, what is the average comparison count?
7. What precondition is required by the binary-search example?
8. What growth class describes 3n² + 2n + 7?
9. A triangular loop runs 1 + 2 + ... + n body operations. Which exact count matches?
10. How many subsets does a set of n distinct elements have?
11. Which pair replaces (a,b) in Euclid’s algorithm?
12. Does a faster computer change an algorithm’s asymptotic order of growth?

Source and further reading

Definitions were transcribed from your 22-page handwritten ADA_UNIT_1_DESIGN_AND_ANALYSIS.pdf. Each quotation identifies its PDF page; grammar and spelling are preserved. New examples, animations, code and mathematical clarifications are labelled as explanations or appear outside the source quotations.

For added analysis: MIT 6.006: asymptotic analysis and NIST: Euclid’s algorithm.

← DAA subject guide