while, do-while, for loops, arrays, and recursive algorithms
if(){}else{} and switch(){case:}In Lecture 2, we learned the fundamentals of activity diagrams:
while loop
// while
int size = 10;
int i = 0;
while (i < size) {
//Some repeated instruction
i++;
}
do-while loop
// while
int size = 10;
int i = 0;
do{
//Some repeated instruction
i++;
} while (i < size);
for loop
// for-loop
String[] table = new String[10];
for (int i = 0; i < 10; i++) {
String current = table[i];
System.out.println(current);
}
// for-loop, "foreach" way
for (String s : table) {
System.out.println(s);
}
//Declares a table of 10 strings
String[] table = new String[10];
int tableLength = table.length;
//Accesses the occurrence at the first index
String occurrence = table[0];
Besides loops, there's another way to repeat operations: recursion
public class RecursionExample {
// Recursive countdown
public static void countdown(int n) {
if (n <= 0) { // Base case: stop when n is 0 or less
System.out.println("Done!");
return;
}
System.out.println(n); // Do something
countdown(n - 1); // Recursive call with smaller problem
}
public static void main(String[] args) {
countdown(5);
// Output: 5, 4, 3, 2, 1, Done!
}
}
How it works: countdown(5) → prints 5 → calls countdown(4) → prints 4 → ... → countdown(0) → prints "Done!"
Factorial: n! = n × (n-1) × (n-2) × ... × 1
Recursive definition: n! = n × (n-1)! and 0! = 1
public static long factorialRecursive(int n) {
// Base case
if (n <= 1) {
return 1;
}
// Recursive case: n! = n * (n-1)!
return n * factorialRecursive(n - 1);
}
// Example: factorialRecursive(4)
// = 4 * factorialRecursive(3)
// = 4 * 3 * factorialRecursive(2)
// = 4 * 3 * 2 * factorialRecursive(1)
// = 4 * 3 * 2 * 1
// = 24
long factorialLoop(int n) {
long result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
long factorialRec(int n) {
if (n <= 1) return 1;
return n * factorialRec(n-1);
}
| Iteration | Recursion | |
|---|---|---|
| Readability | More explicit | Often more elegant |
| Performance | Usually faster | Method call overhead |
| Memory | Constant | Stack grows (risk of overflow) |
Each recursive call adds a frame to the call stack:
factorialRec(4) is called
├── factorialRec(4) waits for factorialRec(3)
│ ├── factorialRec(3) waits for factorialRec(2)
│ │ ├── factorialRec(2) waits for factorialRec(1)
│ │ │ └── factorialRec(1) returns 1 (base case)
│ │ └── factorialRec(2) returns 2 * 1 = 2
│ └── factorialRec(3) returns 3 * 2 = 6
└── factorialRec(4) returns 4 * 6 = 24
StackOverflowError!
public static int sumArray(int[] array, int index) {
// Base case: end of array
if (index >= array.length) {
return 0;
}
// Recursive case: current element + sum of rest
return array[index] + sumArray(array, index + 1);
}
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
int total = sumArray(numbers, 0);
System.out.println("Sum: " + total); // Sum: 15
}
How it works:
FactorialfactorialWhile(int n) - using while loopfactorialDoWhile(int n) - using do-while loopfactorialFor(int n) - using for loopfactorialRecursive(int n) - using recursionstatic void main method calling all four methodsThe Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, ...
Definition: F(n) = F(n-1) + F(n-2), with F(0) = 0 and F(1) = 1
Fibonaccifibonacci(int n)// Hint: structure
public static int fibonacci(int n) {
if (n <= 0) return ???; // Base case 1
if (n == 1) return ???; // Base case 2
return ???; // Recursive case
}