Sorting
Bubble Sort
Repeatedly walk the array comparing adjacent pairs and swapping any that are
out of order. After pass k, the k largest elements are in their final
positions at the end. Stop early when a full pass makes zero swaps.
Algorithm
Canonical input [5, 1, 4, 2, 8] finishes after three passes: two with
swaps, then a clean pass that triggers the early exit. Final array
[1, 2, 4, 5, 8].
adjacent-pair compare and swap
Inner loop walks `j` from `0` to `n - i - 2` comparing `arr(j)` and `arr(j + 1)`.
early exit
A `swapped` flag set false at the start of each pass. If no swap happened, flip a `done` flag and break out of the outer loop.
Basic Implementation
basic.scala
Replay: real traced execution (multi-file project)
object Main {
def main(args: Array[String]): Unit = {
val arr = Array(5, 1, 4, 2, 8)
val n = arr.length
var i = 0
var done = false
while (i < n - 1 && !done) {
var swapped = false
var j = 0
while (j < n - i - 1) {
if (arr(j) > arr(j + 1)) {
val tmp = arr(j)
arr(j) = arr(j + 1)
arr(j + 1) = tmp
swapped = true
}
j = j + 1
}
if (!swapped) {
done = true
}
i = i + 1
}
println(arr.mkString("[", ", ", "]"))
}
}
arr ← [5, 1, 4, 2, 8]
2def main(args: Array[String]): Unit = {3 val arr = Array(5, 1, 4, 2, 8)4 val n = arr.lengthvalues this step[5, 1, 4, 2, 8]arrn ← 5
3val arr = Array(5, 1, 4, 2, 8)4val n = arr.length5var i = 0values this step5n[5, 1, 4, 2, 8]arrswapped ← false
7while (i < n - 1 && !done) {8 var swapped = false9 var j = 0values this stepfalseswappedarr(j) > arr(j+1) ← true
10while (j < n - i - 1) {11 if (arr(j) > arr(j + 1)) {12 val tmp = arr(j)values this steptruearr(j) > arr(j+1)[5, 1, 4, 2, 8]arr0j5arr(j)1arr(j+1)arr ← [1, 5, 4, 2, 8], swapped ← true
12val tmp = arr(j)13arr(j) = arr(j + 1)14arr(j + 1) = tmpvalues this step[5, 1, 4, 2, 8] → [1, 5, 4, 2, 8]arrtrueswappedarr(j) > arr(j+1) ← true
10while (j < n - i - 1) {11 if (arr(j) > arr(j + 1)) {12 val tmp = arr(j)values this steptruearr(j) > arr(j+1)[1, 5, 4, 2, 8]arr1j5arr(j)4arr(j+1)arr ← [1, 4, 5, 2, 8], swapped ← true
12val tmp = arr(j)13arr(j) = arr(j + 1)14arr(j + 1) = tmpvalues this step[1, 5, 4, 2, 8] → [1, 4, 5, 2, 8]arrtrueswappedarr(j) > arr(j+1) ← true
10while (j < n - i - 1) {11 if (arr(j) > arr(j + 1)) {12 val tmp = arr(j)values this steptruearr(j) > arr(j+1)[1, 4, 5, 2, 8]arr2j5arr(j)2arr(j+1)arr ← [1, 4, 2, 5, 8], swapped ← true
12val tmp = arr(j)13arr(j) = arr(j + 1)14arr(j + 1) = tmpvalues this step[1, 4, 5, 2, 8] → [1, 4, 2, 5, 8]arrtrueswappedarr(j) > arr(j+1) ← false
10while (j < n - i - 1) {11 if (arr(j) > arr(j + 1)) {12 val tmp = arr(j)values this stepfalsearr(j) > arr(j+1)[1, 4, 2, 5, 8]arr3j5arr(j)8arr(j+1)swapped ← false
7while (i < n - 1 && !done) {8 var swapped = false9 var j = 0values this stepfalseswappedarr(j) > arr(j+1) ← false
10while (j < n - i - 1) {11 if (arr(j) > arr(j + 1)) {12 val tmp = arr(j)values this stepfalsearr(j) > arr(j+1)[1, 4, 2, 5, 8]arr0j1arr(j)4arr(j+1)arr(j) > arr(j+1) ← true
10while (j < n - i - 1) {11 if (arr(j) > arr(j + 1)) {12 val tmp = arr(j)values this steptruearr(j) > arr(j+1)[1, 4, 2, 5, 8]arr1j4arr(j)2arr(j+1)arr ← [1, 2, 4, 5, 8], swapped ← true
12val tmp = arr(j)13arr(j) = arr(j + 1)14arr(j + 1) = tmpvalues this step[1, 4, 2, 5, 8] → [1, 2, 4, 5, 8]arrtrueswappedarr(j) > arr(j+1) ← false
10while (j < n - i - 1) {11 if (arr(j) > arr(j + 1)) {12 val tmp = arr(j)values this stepfalsearr(j) > arr(j+1)[1, 2, 4, 5, 8]arr2j4arr(j)5arr(j+1)swapped ← false
7while (i < n - 1 && !done) {8 var swapped = false9 var j = 0values this stepfalseswappedarr(j) > arr(j+1) ← false
10while (j < n - i - 1) {11 if (arr(j) > arr(j + 1)) {12 val tmp = arr(j)values this stepfalsearr(j) > arr(j+1)[1, 2, 4, 5, 8]arr0j1arr(j)2arr(j+1)arr(j) > arr(j+1) ← false
10while (j < n - i - 1) {11 if (arr(j) > arr(j + 1)) {12 val tmp = arr(j)values this stepfalsearr(j) > arr(j+1)[1, 2, 4, 5, 8]arr1j2arr(j)4arr(j+1)done ← true
19if (!swapped) {20 done = true21}values this steptruedonefalseswappedstdout ← [1, 2, 4, 5, 8]
23 }24 println(arr.mkString("[", ", ", "]"))25}values this step[1, 2, 4, 5, 8]stdout[1, 2, 4, 5, 8]arr
Complexity
- Time: O(n^2) worst and average; O(n) best (already sorted with early exit)
- Space: O(1)
- Stable: yes
Implementation notes
- Scala: explicit
whileloops withvar i,var j,var done, andvar swappedso the early-exit flow stays visible. The stdlibarr.sortedwould hide the comparison-and-swap the lesson is teaching, andscala.util.boundarywould obscure thedoneflag. - The explicit
val tmp = arr(j); arr(j) = arr(j+1); arr(j+1) = tmpthree-line swap keeps the move visible without leaning on tuple destructuring likeval (a, b) = (arr(j+1), arr(j)). - The replay distinguishes compare frames from swap frames so the
moving pivot value is visible. The pass number and
swappedflag appear in the trace.