Let f(n) = n (n + 1) / 2. Of the following possibilities, state which are true about f and of those, which one best describes the asymptotic class of f ? (Be sure to argue your answers.)
a. | Θ(n2) | b. | O(n2) | c. | Ω(n2) |
d. | Θ(n (n + 1) / 2) | e. | O(n (n + 1) / 2) | f. | Ω(n (n + 1) / 2) |
g. | Θ(n3) | h. | O(n3) | i. | Ω(n3) |
j. | Θ(n log n) | k. | O(n log n) | l. | Ω(n log n) |
m. | Θ(n) | n. | O(n) | o. | Ω(n) |
Answer: all are true except for
g,i : because n2 ≤ O(n3) but NOT ≥ Ω(n3)
j,k : because n2 ≥ Ω(n log n) but NOT ≤ O(n log n)
m,n : because n2 ≥ Ω(n) but NOT ≤ O(n)
The best representative of Θ(n (n + 1) / 2) is (IMO) n2 because it is the simplest.
Which of these statements are best supported by data obtained using search_spy (argue your answer):
Answer: a and d.
a and not b because the data for the fsu:: versions indicates that all searches
require about log n comparisons
d and not c because the data for alt:: versions indicate some
searches require very few comparisons while others require almost n comparisons.
State an asymptotic runtime for each sort algorithm that is best supported by data gathered with sort_spy. Argue your answer using collected data, and also discuss characteristics of the algorithm body that support your answer.
g_selection_sort = Θ(n2)
g_insertion_sort ≤ O(n2)
g_heap_sort ≤ O(n log n)
List::Sort ≤ O(n log n)
Note: These are the best you could do with the data at this time. However, there
is a theoretical result all comparison sorts can have worst-case runtime
better ≥ Ω(n log n), which leads to these more precise statements:
g_selection_sort = Θ(n2)
g_insertion_sort ≤ O(n2)
g_heap_sort = Θ(n log n)
List::Sort = Θ(n log n)
Describe two scenarios, one under which the namespace fsu search algorithms are appropriate and one under which the namespace seq versions are appropriate.
Because the fsu:: and seq:: algorithms have the same assumptions on the data - namely that it is sorted - whenever we can use the fsu:: versions we are better off because they are much faster. So the only situation where we would "choose" the seq:: versions is when we are forced to because the iterators defining the search range are not powerful enough to work with the fsu:: versions. In other words, when the iterators are not random access iterators. The classic case for this is List::Iterator - which are bidirectional iterators but do not have a bracket operator and "pointer" arithmetic.
Short answer: when the data is in a List (not an array, Deque, or Vector)