Algorithm Search⌘K

Proofs: Bubble sort

These are the human proofs of Bubble sort, at full length.

Bubble sort sorts the array and stops full

This proof shows: correctness, termination.

Each change of AA is an exchange of two items, so the multiset of the items never changes. We prove that the order is correct and that the loop stops.

Invariant of the outer loop. At each test of line L2:

(B) A[bound+1…n−1]A[bound+1 \ldots n-1] is sorted in non-decreasing order, and each of its items is at least each item of A[0…bound]A[0 \ldots bound].

Lemma (one pass). Assume (B) at the start of a pass, with bound≥1bound \ge 1. Let A0A_0 be the array at the start of the pass. Then during the pass, just before the comparison of line L5 for index jj, A[j]A[j] is a largest item of A0[0…j]A_0[0 \ldots j]. After the pass, with the value lastlast of line L8:

  1. A[last+1…bound]A[last+1 \ldots bound] is sorted;
  2. each item of A[0…last]A[0 \ldots last] is at most A[last+1]A[last+1].

Proof. The first claim is by induction on jj. For j=0j = 0 no exchange has happened yet, so A[0]=A0[0]A[0] = A_0[0]. Assume it for jj. Lines L5 and L6 put the larger of A[j]A[j] and A[j+1]A[j+1] at j+1j+1. The item A[j+1]A[j+1] was not touched before step jj, so it is A0[j+1]A_0[j+1]. So after the step, A[j+1]A[j+1] is a largest item of A0[0…j+1]A_0[0 \ldots j+1], and the item at j+1j+1 is not changed again before the comparison for j+1j + 1.

Now the two claims. After the last step of the pass, A[bound]A[bound] is a largest item of A0[0…bound]A_0[0 \ldots bound] by the first claim. Consider the steps j=last+1,…,bound−1j = last+1, \ldots, bound-1. By the definition of lastlast, line L5 found no pair out of order in these steps, so A[j]≤A[j+1]A[j] \le A[j+1] at each of them, and these positions were not changed after their step. So A[last+1]≤A[last+2]≤⋯≤A[bound]A[last+1] \le A[last+2] \le \cdots \le A[bound], which is claim 1. For claim 2, there are two cases. If the pass made an exchange, the last one was at j=lastj = last, and it put at last+1last + 1 a largest item of A0[0…last+1]A_0[0 \ldots last+1], which is at least each item now in A[0…last]A[0 \ldots last], because those items are a sub-multiset of A0[0…last+1]A_0[0 \ldots last+1] minus this one item. If the pass made no exchange, then last=0last = 0, and the step j=0j = 0 found A[0]≤A[1]A[0] \le A[1]. □\square

Theorem. BUBBLE-SORT(A)(A) stops after at most n−1n - 1 passes, and after it AA is sorted.

Proof. Initialization. Line L1 sets bound=n−1bound = n - 1. Then A[bound+1…n−1]A[bound+1 \ldots n-1] is empty, so (B) holds.

Maintenance. Assume (B) and bound≥1bound \ge 1, and let lastlast be the value after the pass. The pass changes only A[0…bound]A[0 \ldots bound], so A[bound+1…n−1]A[bound+1 \ldots n-1] is unchanged and still sorted, and its items are still at least each item of A[0…bound]A[0 \ldots bound], since this part holds the same multiset as before. By the lemma, A[last+1…bound]A[last+1 \ldots bound] is sorted. Its last item A[bound]A[bound] is an item of A[0…bound]A[0 \ldots bound], so it is at most A[bound+1]A[bound+1]. So A[last+1…n−1]A[last+1 \ldots n-1] is sorted. Each item of A[0…last]A[0 \ldots last] is at most A[last+1]A[last+1] by claim 2 of the lemma, and so at most each item of A[last+1…n−1]A[last+1 \ldots n-1]. Line L8 sets bound←lastbound \leftarrow last, and (B) holds.

Termination. In a pass, line L7 sets lastlast only to values j≤bound−1j \le bound - 1, and line L3 sets it to 0≤bound−10 \le bound - 1. So each pass makes boundbound smaller by at least 1. It starts at n−1n - 1 and the loop runs while bound>0bound > 0, so there are at most n−1n - 1 passes. When the loop stops, bound≤0bound \le 0. If n≥1n \ge 1, then bound=0bound = 0, and (B) says that A[1…n−1]A[1 \ldots n-1] is sorted and that A[0]A[0] is at most each of its items, so AA is sorted. If n=0n = 0, the array is empty. ■\blacksquare

Stability. Line L5 exchanges two items only when the left one is strictly larger. So two equal items are never exchanged. An item moves only by exchanges with its neighbour, so it can pass an equal item only by an exchange with it. So equal items keep their relative order.

Exchanges. Each exchange of line L6 swaps a pair A[j]>A[j+1]A[j] > A[j+1] of neighbours. This pair is an inversion, and the exchange changes no other pair of items, so it lowers the number of inversions by exactly 1. The sorted array has none. So the number of exchanges equals the number of inversions of the input.

Back to Bubble sort