Cmpt 125 Study Notes
-
Upload
monique-lai -
Category
Documents
-
view
23 -
download
3
description
Transcript of Cmpt 125 Study Notes
Declarative: statements of facts
- What is ... ?
- The maximum value of a, b, c is the one no smaller than any of the other two
Imperative: procedures (recipes)
- How to do ... ?
- A sequence of steps to compute the maximum
Declarative:
The square root of y is a number x such that x*x = y
Imperative:
How to compute the square root of a number, such as 10 ?
Syntax:
Which sequences of characters and symbols are well-formed strings?
Semantics:
Which well-formed strings have a meaning?
What is that meaning?
Programming languages are written based on a grammar (just like English.) Grammars might say something like "If statements always have the form: if (condition) then (statement)." If you write something that follows the grammar perfectly, then it is syntactically correct, but may or may not be semantically correct, or semantically meaningful.
In some arbitrary simple language, the statement:
int i = "hello"is syntactically correct, but not semantically correct, since it has no meaning even though it correctly follows the structure of the language.
A very common example is Chomsky's statement "Colorless green ideas sleep furiously", which follows the grammar of the English language but is semantically incorrect because it because it contains several contradictions -- colorless things cannot be green, for instance. You could of course argue this poetically to have some meaning (I would probably hate you), but that's beyond the scope of this discussion.
In English, "I no like!" is grammatically incorrect (syntactically incorrect), but is not semantically incorrect since it does imbue some meaning.
In coding, this is more muddy; it's hard to say whether a statement like "i (int) = 3" is semantically correct even though it's syntactically correct. There's really no meaning in this distinction, either. Generally, a statement has to be syntactically valid before it even has a chance of being semantically valid.
Syntax is the grammar. It describes the way to construct a correct sentence. For example, this water is triangular is syntactically correct.
Semantics relates to the meaning. this water is triangular does not mean anything, though the grammar is ok.
Computation is mainly about the process of solving problems using computers
Programming is to design and implement solutions using languages that are understandable by computers
// Print out "Hello World"
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");}
}
Primitive Data Typesbyte, short, int, long 8, 125float, double 3.14159char'a','A'boolean true, false
Object Types -- ClassesString"SFU"
A Variable is a name for memory location
● Declaration: specify the type and name
● Assignment: give values to variables
● Postfix
i++; i--;
● Prefix
++i; --i;
● The value of a postfix expression:
the value of the variable before incremented
● The value of a prefix expression:
the value of the variable after incremented
a = i++; a = ++i;
a = i; i = i + 1;
i = i + 1; a = i;
Logical operators take boolean operands and produce boolean results
! (NOT) && (AND) || (OR)
● ! (NOT) has one operand (unary)
&& (AND), || (OR) have two operands
● Operands and results are all boolean
● ! has higher precedence than &&, ||
! found && isValid
(! found) && isValid
Relational operators take two operands and return boolean results
> < >= <=
== (equal to)
!= (not equal to)
int a = 3, b = 4;
boolean isEq = (a == b);
boolean notEq = (a != b);
● The Scanner class provides methods for reading input
● Keyboard input -- System.in
Scanner scan = new Scanner(System.in);
String message = scan.nextLine();
System.out.println("You message is: " + "\"" + message + "\"");
System.out.println("Type in integer: ");
int a = scan.nextInt();
System.out.println ("Your integer is: " + a);
● String nextLine()
Returns the rest of the current line
● String next()
Returns the next token (delimited by whitespace)
● int nextInt()
Scans the next token of the input as an int
● double nextDouble()
Scans the next token of the input as a double
<cond_statement> ::=
if ( <bool_expr> )
<statement1>
else
<statement2>
if (a < b)
min = a;
else
min = b;
A conditional operator uses a boolean condition to determine which of two expressions is evaluated
condition ? expression1 : expression2
min = (a < b) ? a : b;
min3 = (a < b && a < c) ? a :
( (b < c) ? b : c );
● Check the condition
● If true, run the statement, and repeat
● If false, skip the statement
int num = 10;
long factorial = 1;
int i = 1;
while (i <= num)
{
factorial *= i;
i++;
}
<for statement> ::=
for ( initialization; condition; increment )
<statement>
int i = 0, sum = 0;
for (i = 1; i <= 10; i++)
{
sum = sum + i;
}
Infinite Loop
int count = 1;
while (count > 0 || count <= 0)
{
count = count + 1;
}
● The condition is never false
● Terminate the program with “Control + C”
● Use break to terminate a loop
while (true)
{
boolean found = false;
......
if (found) // found and get out
break;
......
}
● Use continue to skip the rest of loop body
while (true)
{
boolean found = false;
......
if (! found) // not found, do again
continue;
......
}
How to design / develop / maintain?
● Decomposition: break up into modules
● Abstraction: suppress details
Two Views of Classes
● Code Library: a collection of functions
● Math class contains tools for performing basic numeric operations
double a = Math.sqrt(121);
● Object Data Type: a concept
● String class represents character strings
String str = "Simon Fraser";
Packages
● Java classes are grouped into packages
● Java class libraries:
java.lang: System, Math, String
java.util: Scanner, Date
● The import declaration
import java.util.Scanner;
import java.util.*;
Classes as Object Data Types
● A class represents a concept
● An object instantiates a concept
String str = "Simon Fraser";
String str2 = str;
int a = 10;
● A class is the blueprint of an object
● Multiple objects can be created from the same class
A class has two kinds of members
● fields - what it is (data, attributes)
● methods - what it can do (operations)
● A field is a class-level variable
● A method is a collection of statements to be run when it is called
● Methods provide ways to access fields of an object
● String class represents character strings
String str = "Simon Fraser";
● Fields are hidden from the user
● Methods are provided as interfaces to
- compare strings
- extract substrings ……
● Strings are not changeable after created
● Fields and methods are accessed using the dot (.) operator (with a specific object)
objectVariable.methodName(argumentList)
● int length()
Returns the number of characters
String str = "Simon Fraser";
int len = str.length();
● boolean equals(String s)
Returns true if the argument represents the same sequence of characters
boolean eq = str.equals(str2);
● int compareTo(String s)
Returns a negative integer if this String object lexicographically precedes the argument string. The result is zero if the strings are equal.
int cmp = str.compareTo(str2);
● boolean startsWith(String prefix)
Returns true if the String starts with the prefix
boolean b = str.startsWith("Simon");
● char charAt(int index)
Returns the char at the specified index.
An index ranges from 0 to length() - 1
char c = str.charAt(0);
● String substring(int beginIndex,
int endIndex)
Returns a substring begins at beginIndex and extends to the character at index endIndex - 1
String str = "Simon Fraser";
String a = str.substring(0, 3);
String b = str.substring(1, 3);
● new operator: create a new object
● Constructor method: initialize objects
● A constructor has the same name as its class
String str = "Simon Fraser";
String str2 = new String("Simon Fraser");
Scanner scan = new Scanner(System.in);
Classes as Collections of Functions
● Java does not have stand-alone functions
● Static methods are associated with classes, not objects
● Math class contains functions for performing basic numeric operations
double a = Math.abs(-121);
double s = Math.sqrt(121);
double r = Math.random();
Generate a random number between 0.0 and 1.0
● A method is a collection of statements
- Header: return type, name, parameters
- Body: statements, return
static int min (int a, int b, int c)
{
if (a < b && a < c)
return a;
if (b < c)
return b;
return c;
}
● Static methods are called through the class name (not object variables)
public class MyMathTest
{
public static void main(String[]args)
{
int c = MyMath.cube(5);
int m = MyMath.min(5, 4, 3);
double a = Math.abs(-121);
}
}
A method is a collection of statements
● Header: return type, name, parameters
● Body: statements, return
static int min (int a, int b, int c)
{
if (a < b && a < c)
return a;
if (b < c)
return b;
return c;
}
Functional call: transfer of control flow
main() → max()
Parameter variables are initialized with the values passed from the call
● Scope: where a variable is referable
● The scope is usually delimited by {}
● Just one return value, matching with the return type
● Use void as return type, if no returns
● The call ends whenever there is a return
● Every branch must have a return
static int max (int a, int b, int c)
{
if (a > b && a > c) return a;
if (b > c) return b;
return c;
}
Static methods are called through the class name (not object variables)
An array stores a sequence of values that are all of the same type
int[] arr = {38, 27, 43, 3, 9, 82, 10};
int[] arr = new int[7];
arr[0] = 38;
arr[1] = 27; ......
● Zero-based indexing
The first element of arr[] is arr[0]
● Array length
Once created, the array size is fixed:
arr.length
● Bounds checking
Use legal indices to access elements
0, ..., arr.length-1
Process all elements from the lowest index(0) to the highest index (length-1)
for (int i = 0; i < arr.length; i++)
System.out.println(arr[i]);
for (int elem : arr)
System.out.println(elem);
Find the Minimum Value
for (int i = 1; i < arr.length; i++)
if (arr[i] < min)
min = arr[i];
Find the Index of the Minimum
static int minIndex (int[] arr)
{
int index = 0, min = arr[0];
for (int i = 1; i < arr.length; i++)
{
if (arr[i] < min)
{
min = arr[i];
index = i;
}
}
return index;
}
static double average (int[] arr)
{
int sum = 0;
for (int i = 0; i < arr.length; i++)
sum += arr[i];
return (double) sum / arr.length;
}
for (int elem : arr)
sum += elem;
Concatenate Two Arrays
static int[] concatenate (int[] a, int[] b)
{
int[] newArr = new int[a.length + b.length];
int i = 0;
for (int elem : a) // copy the 1st array
newArr[i++] = elem;
for (int elem : b) // copy the 2nd array
newArr[i++] = elem;
return newArr;
}
Arrays Are Objects
int[] arr = {38, 27, 43, 3, 9};
int[] b = arr;
b[0]++;
● An object variable is a reference/pointer
● Assigning an object variable only passes the reference
public static void dummyIncrease (int[] arr, int b)
{
arr[0] += 1; // arr[0] == ???
b += 1; // b == ???
}
public static void main(String[] args)
{
int[] arr = {38, 27, 43, 3, 9};
int b = 1;
dummyIncrease(arr, b); // arr[0] == ???, b == ???
}
When an object variable is passed as a parameter to a method, it still refers to the original object
String[] words = new String[5];
words[0] = "friendship";
words[1] = "loyalty";
words[2] = "honor";
Object references as array elements:
String[] words = new String[5];
words[0] = "friendship";
words[1] = "loyalty";
words[2] = "honor";
String[] words = {"friendship", "loyalty", "honor"};
● With the new operator, the array will be initialized with null references
int[][] matrix = { {11, 12, 13},
{21, 22, 23} };
● An element is referenced using two indices
matrix[0][1] = 12;
● Each row can be specified using one index
int[] arr = matrix[0];
int[][] arr = {
{11, 12, 13},
{21, 22, 23, 24},
{31, 32}
};
for (int i = 0; i < arr.length; i++)
{
for (int j = 0; j < arr[i].length; j++)
System.out.print(arr[i][j] + " ");
System.out.println();
}
public static boolean equals(int[] a, int[] a2)
Returns true if the two specified arrays of ints are equal. Two arrays are equal if they contain the same elements in the same order. Also, they are equal if both are null.
Parameters:
a, a2 - arrays to be tested for equality
Returns:
true if the two arrays are equal
public static boolean equals(int[] a1, int[] a2){
if (a1 == a2) return true;
if (null == a1 || null == a2) return false;
if (a1.length != a2.length) return false;
int i = a1.length;
while (--i >= 0)
if (a1[i] != a2[i]) return false;
return true;
}
Math.random() returns random double value between 0.0 (inclusive) and 1.0 (exclusive)
int length = 10,
max = 100;
int[] arr = new int[length];
for (int i = 0; i < length; i++)
arr[i] = (int) (Math.random() * max);
System.out.println(Arrays.toString(arr));
Input/Output Streams
An I/O Stream represents an input source or an output destination
● The Scanner class provides methods for reading input from various sources
● Keyboard input is via the System.in object
Scanner scan = new Scanner(System.in);
String msg = scan.nextLine();
System.out.println("You message is: " + msg);
● public String nextLine()
Returns the rest of the current line. The position is set to the beginning of the next line
● public int nextInt()
Scans the next token of the input as an int
● public int hasNextInt()
Returns true if the next token can be interpreted as an int value
Path:
● In Unix/Linux/Mac OS
/home/sally/statusReport
● In Windows
C:\home\sally\statusReport
A file is identified by its path through the
file system
● java.io.PrintWriter is a class for writing to text files
public PrintWriter(String fileName)
● If the file exists, it will be truncated; otherwise, a new file will be created
PrintWriter out = new PrintWriter("test.txt");
out.println("Some text here");
out.close();
import java.io.FileNotFoundException;
import java.io.PrintWriter;
public class WriteFile
{
public static void main(String[] args)
throws FileNotFoundException
{
PrintWriter out = new PrintWriter("random.txt");
for (int line = 1; line <= 100; line++)
{
String str = line + ": " + Math.random();
out.println(str);
}
out.close();
}
}
Read Text Files
● java.util.Scanner
a class for reading text inputs
● java.io.File
an abstract representation of file pathnames
File file = new File(“test.txt”)
Scanner scan = new Scanner(file);
String str = scan.nextLine();
import java.util.Scanner;
import java.io.*;
public class ReadFile
{
public static void main (String[] args)
throws FileNotFoundException
{
File file = new File("random.txt");
Scanner scan = new Scanner(file);
while (scan.hasNext())
{
String str = scan.nextLine();
System.out.println(str);
}
scan.close();
}
}
URL (Uniform Resource Locator)
● A URL is a pointer to a "resource" on the Internet
http://www.sfu.ca/index.html
● “http”: HyperText Transfer Protocol
● “www.sfu.ca” is the host machine name
● “index.html” is the file we are looking for
● This URL points to an HTML file
(HyperText Markup Language)
public class ReadURL
{
public static void main(String[] args) throws IOException
{
URL url = new URL("http://www.sfu.ca/");
InputStream in = url.openStream();
Scanner scan = new Scanner(in);
int line = 1;
while (scan.hasNext())
{
String str = scan.nextLine();
System.out.println(line + ": " + str);
line++;
}
scan.close();
}
}
Exercise: Find Title in HTMLDesign a program that
● gets a URL from users' inputs
● retrieves the HTML content of the URL
● finds the "title" from the content
public class ReadURLTitle{
// Read from URL and return the content in a Stringpublic static String readURLContent(String urlString)
{ ……}
// Find title within the HTML contentpublic static String findTitle(String str){ ……}
public static void main(String[] args) throws IOException {
String str = ……;String content = readURLContent(str); String title = findTitle(content);System.out.println(title);
}}
● Absolute path contains the full directory:
/home/sally/statusReport (in Unix/MacOS)
C:\home\sally\statusReport (in Windows)
● Relative path is relative to the directory that the program is in
statusReport (in folder /home/sally)
sally/statusReport (in folder /home)
File file = new File("random.txt");
String p = file.getCanonicalPath();
● java.lang: general; automatically loaded
System, String, Math
● java.util: general utilities
Scanner, Arrays
● java.io: input/output
File, InputStream, PrintWriter
● java.net: internet
URL
● An object is referable only when there is a reference (object variable) to it
● Java automatically maintains a count of object references and collects garbage
String a = new String(“Hello World”);
String b = new String(“Hi World”);
b = a;
What Is Recursion
● Recursion is the process of
repeating items in a self-similar way
Recursive definitions:
● An ancestor is (1) a parent, or (2) a parent of an ancestor
● A variable or a constant is an expression; if E and F are expressions, then so are
(E), E + F, E - F, ……
A class of objects has recursive behavior if they can be defined by:
● A simple base case, and
● A set of rules reducing other cases to the base case
Factorial function n!
● n = 1: 1! = 1
● n > 1: n! = n * (n-1)!
public static long
factorial (int n)
{
if (n <= 1)
return 1;
return n * factorial(n-1);
}
public static long factorial(int n)
{
if (n <= 1)
return 1;
return n * factorial(n - 1);
}
public static long factorialWithLoop(int n)
{
long f = 1;
for (int i = 2; i <= n; i++)
f = f * i;
return f;
}
Palindrome
public static boolean isPalindrome(String s)
{
if (s.length() <= 1)
return true;
if (s.charAt(0) == s.charAt(s.length() - 1))
{
String substr = s.substring(1, s.length() - 1);
return isPalindrome(substr);
}
return false;
}
// "civic", "radar", "level"
● Euclid's algorithm
For positive integers p, q where p > q,
GCD(p, q) == GCD(q, p%q)
public static int gcd (int p, int q)
{
if (p < q)
return gcd(q, p);
if (q == 0)
return p;
return gcd(q, p % q);
public static void moveTower(int n, int start, int dest, int extra)
{
if (n <= 1)
System.out.println(start + " --> " + dest);
else
{moveTower (n - 1, start, extra, dest);
System.out.println (start + " --> " + dest);
moveTower (n - 1, extra, dest, start);
}
}
……
moveTower(totalDisks, 1, 3, 2);
public static void exchange (int a, int b, int n)
{
System.out.println("before: " + n + " a:" + a + " b:"+ b);
if (n > 1)
exchange (b, a, n - 1);
System.out.println("after: " + n + " a:" + a + " b:"+ b);
}
……
exchange(100, 200, 3);
Searching
Find a target within a group of elements, or determine the target does not exist
INPUT: an array, a target
OUTPUT: the index of the target in the array
ALGORITHM:
● Access each element one by one:
If it is the target, return the index;
Otherwise, continue (to the next elem.)
● Return “not found”
Linear Search
public static int
linearSearch(int[] arr, int target)
{
for (int i = 0; i < arr.length; i++)
{
if (arr[i] == target)
return i;
}
return -1;
}
Binary Search
● If the middle element is the target, done
● Otherwise, divide the array in halfs and search either left or right
INPUT: an array, a target
OUTPUT: the index of the target
ALGORITHM:
Compare the target with the middle element
● If equal, return the middle index
● If target is bigger, search the right half
● If target is smaller, search the left half
Binary search does not work for unsorted arrays
// a recursive binary search
public static int
binarySearch (int[] arr, int first, int last, int target)
{if (first > last)
return -1;// not found
int mid = (first + last) / 2;
if (target == arr[mid])return mid; // done
if (target > arr[mid])first = mid + 1; // right half
else
last = mid - 1; // left half
return binarySearch(arr, first, last, target);}
……
int index = binarySearch(arr, 0, arr.length-1, target);
● For a sorted array, which search algorithm is more efficient?
Linear search vs. binary search
● Efficiency
The change of running time as the input (array) size increases
● Many factors affect the running time
- programming language, hardware, ……
- input size
● Time Complexity of an Algorithm:
The running time expressed as a function of the input size:
t(n) = 2*n + 5
Design efficient algorithms to
1. Find the minimum value in an array
2. Find the minimum value in a sorted array
3. Compute average of elements in an array
4. Compare each pair of elements in an array
Selection Sort Code
public static void selectionSort(int[] data)
{
for (int i = 0; i < data.length - 1; i++)
{
int minIndex = i;
for (int j = i + 1; j < data.length; j++)
{
if (data[j] < data[minIndex])
minIndex = j;
}
swap it to index i
}
}
Insertion Sort
Maintain a sorted subarray and repeatedly insert elements into it
● Take the 1st element as a sorted subarray
● Insert the 2nd element into the sorted subarray
● Shift elements if necessary
● Repeat until all elements are inserted
● public static void insertionSort(int[] data)
● {
● for (int i = 1; i < data.length; i++)
● {
● int temp = data[i]; // i-th element
● int j;
● for (j = i; j > 0; j--) // shifting
● {
● if (data[j - 1] < temp)
● break;
● data[j] = data[j - 1];
● }
● data[j] = temp; // insertion
● }
● }
Insertion Sort Running Time
Suppose the array has length n
● The outer loop runs n-1 passes
● In each pass of the outer loop, the inner loop runs about n/2 passes on average
● The total time is about
t(n) = O(n2)
Bubble Sort
Repetitively compare adjacent elements and swap if necessary
● Scan the array
● Exchange two adjacent elements if they are not in order
(The largest value bubbles up to the end)
● Scan the array again; the 2nd largest value bubbles up
● Repeat ......
public static void bubbleSort(int[] data)
{
For each index in array (starting from the end):
{
Bubble up the largest element
by comparing adjacent pairs
and swapping when necessary
}
}
public static void bubbleSort(int[] data)
{
for (int i = data.length - 1; i > 0; i--)
{
for (int j = 0; j <= i - 1; j++)
{
if (data[j] > data[j + 1])
swap(data, j, j + 1);
}
}
}
Suppose the array has length n
● The outer loop runs roughly n passes
● In each pass of the outer loop, the inner loop runs roughly n/2 passes on average
● The total time is about
n * n/2 = O(n2)
● Selection sort
Repeatedly choose the smallest element
● Insertion sort
Repeatedly insert into a sorted subarray
● Bubble sort
Repeatedly compare neighbors and swap
● All based on pairwise comparisons
● Total number of comparisons: O(n2)
Merge Sort
Recursively divide and merge
● Divide the array in half
● Recursively divide until each subarray has only one element
● Merge (sorted) subarrays in order
public static void mergeSort (int[] data, int first, int last)
{
Return if the array has one element;
Divide the array into two parts:
Call mergeSort on the left part;
Call mergeSort on the right part;
Merge left and right parts in order
}
// mergeSort (array, 0, array.length - 1);
public static void mergeSort (int[] data, int first, int last)
{
if (first >= last)
return;
int mid = (first + last) / 2;
mergeSort(data, first, mid);
mergeSort(data, mid + 1, last);
merge (data, first, last);
}
……
mergeSort(array, 0, array.length - 1);
● Initialize a temporary storage for the merged result
● Start from beginning of both subarrays
● Choose the smaller element, copy it to the temporary storage
● Move forward and repeat
● When one subarray finishes, copy the rest of the other subarray
●
A postfix expression evaluates to be the value of the variable before incremented
public static void merge(int[] data, int first, int last)
{
int[] temp = new int[last - first + 1];
int mid = (first + last) / 2;
int i = first, j = mid + 1, k = 0;
while (i <= mid && j <= last)
{
if (data[i] < data[j]) temp[k++] = data[i++];
else temp[k++] = data[j++];
}
while (i <= mid) temp[k++] = data[i++];
while (j <= last) temp[k++] = data[j++];
for (i = first; i <= last; i++)
data[i] = temp[i - first];
}
Efficiency of Merge Sort
Suppose the array has n elements
● Recursively divide the array in half
● There are totally log(n) levels of divisions
● Merging on each level requires linear time
● The total running time is
O(n * log(n))
Divide and Conquer
● Recursively break down a problem into two sub-problems of the same type, until they become simple enough to be solved directly
● Solutions to the sub-problems are then combined to give a solution to the original problem
Merge Sort
Divide and conquer
● Break down a big problem
into sub-problems
● Combine solutions to
sub-problems
● Running time is
O(n * log(n))
Quick Sort
Sort an array of number:
● Choose one element as the pivot
● Partitioning:
Move smaller elements to the left, and larger elements to the right
(the pivot in the middle)
● Repeat this recursively on both parts
public static void
quickSort (int[] data, int first, int last)
{
If the length is <=1, return;
Choose a pivot and partition the array;
Sort the left part;
Sort the right part;
}
// quickSort (array, 0, array.length - 1);
public static void
quickSort(int[] data, int first, int last)
{
if (first >= last)
return;
int pivot = partition (data, first, last);
quickSort(data, first, pivot - 1); // left
quickSort(data, pivot + 1, last); // right
}
Partitioning
● Make a temporary array holding the result
● Choose a pivot: the first element
● Scan the array:
Put smaller elements to the left end;
Put larger elements to the right end
● Put the pivot in the middle
● Copy back
public static int partition (int[] data, int first, int last)
{
int[] temp = new int[last - first + 1];
int pivot = data[first];
int i = 0, j = last - first, k;
for (k = first + 1; k <= last; k++)
{
if (data[k] <= pivot) temp[i++] = data[k];
else temp[j--] = data[k];
}
temp[i] = pivot;
for (k = first; k <= last; k++)
data[k] = temp[k - first];
return first + i;
}
In-Place Partitioning
● Choose a pivot: the first element
● Scan the array from both ends towards the middle
● Whenever finding two elements on the wrong side, swap them
● When the scans meet in the middle, swap the pivot with this middle element
public static int partition2(int[] data, int first, int last)
{
int pivot = data[first];
int left = first, right = last;
while (left < right)
{
while (data[left] <= pivot && left < right)
left++;
while (data[right] > pivot)
right--;
if (left < right)
swap (data, left, right);
}
swap (data, first, right);
return right;
}
Suppose the array has n elements
● On average, each partitioning divides the array in half
● There are log(n) levels of partitioning
● Partitioning in each level takes linear time
● On average, the total time is about
O(n * log(n))
Suppose the array has length n
What will be the running time if the pivot is always chosen to be
● the smallest element? O(n2)
● the median element? O(n log(n))
● a random element? on avg. O(n log(n))
● Worst-case vs. average-case
● Recursively break down a problem into two sub-problems of the same type, until they are simple enough to be solved directly
● The solutions to the sub-problems are then combined to give a solution to the original problem
● Merge sort, quick sort
● Selection Sort: repeatedly find the smallest value and save to its final position
● Insertion Sort: repeatedly insert a value into a sorted subarray
● Bubble Sort: repeatedly compare neighboring pairs & swap if necessary
● Merge Sort: Recursively divide in half and then merge the parts in sorted order
● Quick Sort: Recursively partition into two parts around a pivot and sort each part
Comparing pairs O(n2)
● Insertion Sort
● Selection Sort
● Bubble Sort
Divide-and-conquer O(n * log n)
● Merge Sort
● Quick Sort (average-case)