Recursive algorithm


A recursive algorithm is an algorithm that calls itself. It has base case(s) for problems it can trivially solve, and recursive case(s) for problems that must be reduced in some way before being called on by the algorithm again. It's generally a good rule of thumb to use recursion when the answer to a problem can be constructed from the answers to similar subproblems.

Here's a recursive algorithm for computing factorials:

algorithm factorial is
input: an integer n ≥ 0
output: n!

if n = 0 (base case)
return 1
else (recursive case)
return n * factorial(n - 1)
⚠ The recursive depth of this algorithm quickly becomes overwhelming. It's not recommended to use this to compute the factorial of even a moderately large integer.

The recursive algorithm for computing Fibonacci numbers calls itself more than once in its recursive case. Take a look:

algorithm fibonacci is
input: an integer n ≥ 0
output: the nth fibonacci number

if n = 0 (base case)
return 0
else if n = 1 (another base case)
return 1
else (recursive case)
return fibonacci(n - 1) + fibonacci(n - 2)

Unfortunately, directly adapting the recursive definition of the Fibonacci sequence into an algorithm doesn't really work. The above algorithm is terribly inefficient and causes plenty of redundant calls to be made. If you make note of each time the algorithm makes a recursive call, you'll see that many calls are for computing Fibonacci numbers that have already been previously computed. A more efficient, non-recursive implementation that "remembers" previously computed Fibonacci numbers is given below:

algorithm efficient_fibonacci is
input: an integer n ≥ 0
output: the nth fibonacci number

f ← [0, 1]
for i = 2 to n
append f[i - 1] + f[i - 2] to f
return f[n]

This bottom-up approach to computing Fibonacci numbers is an example of dynamic programming. It closely resembles how people actually compute Fibonacci numbers with a pen and paper. So, when designing algorithms, it might be helpful to think about how someone would practically solve the problem without a computer.

Logic & Proofs
IntegerRational numberInequalityReal numberTheoremProofStatementProof by exhaustionUniversal generalizationCounterexampleExistence proofExistential instantiationAxiomLogicTruthPropositionCompound propositionLogical operationLogical equivalenceTautologyContradictionLogic lawPredicateDomainQuantifierArgumentRule of inferenceLogical proofDirect proofProof by contrapositiveIrrational numberProof by contradictionProof by casesSummationDisjunctive normal form
Set Theory
SetElementEmpty setUniversal setSubsetPower setCartesian productStringBinary stringEmpty stringSet operationSet identitySet proof
Functions
FunctionFloor functionCeiling functionInverse function
Algorithms
AlgorithmPseudocodeCommandAsymptotic notationTime complexityAtomic operationBrute-force algorithm
Relations
RelationReflexive relationSymmetric relationTransitive relationRelation compositionEquivalence relationEquivalence class
Number Theory
Integer divisionLinear combinationDivision algorithmModular arithmeticPrime factorizationGreatest common divisorLeast common multiplePrimality testFactoring algorithmEuclid's theoremPrime number theoremEuclidean algorithm
Induction
Proof by inductionFibonacci sequenceProof by strong inductionWell-ordering principleSequenceFactorialRecursive definition
Combinatorics
Rule of productRule of sumBijection rulePermutationCombinationComplement ruleExperimentOutcomeSample spaceEventProbabilityProbability distributionUniform distributionMultisetSixfold wayInclusion-exclusion principlePigeonhole principle
Graph Theory
GraphWalkSubgraphRegular graphComplete graphEmpty graphCycle graphHypercube graphBipartite graphComponentEulerian circuitEulerian trailHamiltonian cycleHamiltonian pathTreeHuffman treeSubstringForestPath graphStarSpanning treeWeighted graphMinimum spanning treeGreedy algorithmPrim's algorithm
Recursion
RecursionRecursive algorithmCorrectness proofDivide-and-conquer algorithmSorting algorithmMerge sort