The cost table: pick a collection by what it costs
A data structure is a trade-off: it makes some operations cheap by making others expensive. Big-O describes how the work grows as the input grows: O(1) is "the same work no matter how big", O(n) is "work grows in step with the size", O(log n) is "doubling the input adds one step". Scala adds a second axis: immutable collections share structure between versions, so "adding" returns a new collection cheaply without copying everything.
| Collection | Index / lookup | Prepend | Append | Built on |
|---|---|---|---|---|
List | O(n) | O(1) :: | O(n) :+ | singly linked cons cells |
Vector | effectively O(1) | effectively O(1) | effectively O(1) | wide tree (32-way) |
Array | O(1) | — copy | — copy | JVM array, mutable, fixed size |
mutable.ArrayBuffer | O(1) | O(n) | O(1) amortised | resizable array |
Map / Set (hash) | O(1) effectively | — | O(1) effectively | hash trie (immutable) or hash table (mutable) |
TreeMap / TreeSet | O(log n) | — | O(log n) | red-black tree, kept sorted |
immutable.Queue | O(n) | — | O(1) enqueue | two lists, amortised O(1) dequeue |
mutable.PriorityQueue | O(1) head (max) | — | O(log n) | binary heap |
@main def run(): Unit =
val data = Vector.range(0, 1_000_000)
val target = 999_999
var linearSteps = 0
val it = data.iterator
var found = false
while !found && it.hasNext do
linearSteps += 1
if it.next() == target then found = true
var binarySteps = 0
var lo = 0
var hi = data.length - 1
var done = false
while !done && lo <= hi do
binarySteps += 1
val mid = lo + (hi - lo) / 2
if data(mid) == target then done = true
else if data(mid) < target then lo = mid + 1
else hi = mid - 1
println(s"Linear search: $linearSteps steps")
println(s"Binary search: $binarySteps steps")Linear search: 1000000 steps
Binary search: 20 stepsThe same question, "where is 999,999?", answered by an O(n) and an O(log n) algorithm over one million sorted numbers. Scala has no break, so the loops stop with a flag.
Replace the hand-written binary search with the standard one: data.search(target) returns Found(index) or InsertionPoint(index). Print both cases.
