Vòng trong ngắn dần
Ở phiên bản nổi bọt không dừng sớm của SGK, lượt ngoài đầu so sánh `n−1` cặp kề nhau; lượt sau `n−2` cặp; tiếp tục đến 1 cặp. Tổng số so sánh là `n(n−1)/2`, nên bậc thời gian là `O(n²)`. Mỗi lần hai phần tử sai thứ tự mới đổi chỗ. Vì vậy số lần đổi chỗ **phụ thuộc dãy đầu vào**: dãy đã tăng có thể không đổi chỗ lần nào, dù vòng lặp vẫn so sánh đủ các cặp.
Đếm riêng hai loại thao tác
```python
def noi_bot_va_dem(a):
so_sanh = 0
doi_cho = 0
n = len(a)
for i in range(n - 1):
for j in range(n - 1 - i):
so_sanh += 1
if a[j] > a[j + 1]:
a[j], a[j + 1] = a[j + 1], a[j]
doi_cho += 1
return so_sanh, doi_cho
day = [3, 1, 2]
print(noi_bot_va_dem(day), day)
```
Kết quả là `(3, 2) [1, 2, 3]`: ba so sánh, hai lần đổi chỗ. Với `[1, 2, 3]`, vẫn có ba so sánh nhưng không đổi chỗ. Do đó công thức giả định **mọi lần so sánh đều đổi chỗ** chỉ là một cách chặn trên chi phí, không phải số thao tác thực tế của mọi dãy.
Bài luyện
Phiên bản nổi bọt trong bài so sánh bao nhiêu cặp khi `n = 4`?
Mới là lượt đầu.
Không phải tổng lượt.
3+2+1=6.
Vòng trong ngắn dần, không phải 4×4.
Lời giải
Các lượt ngoài xét 3, 2, 1 cặp; tổng là 6.
Bài luyện
Với `a = [1, 2, 3]`, `noi_bot_va_dem(a)` trả cặp số đếm nào?
Mã không có dừng sớm nên vẫn so sánh.
Ba cặp được so sánh, không cặp nào sai thứ tự.
Không có đổi chỗ.
Không thể đổi chỗ khi chưa so sánh.
Lời giải
Vòng lặp vẫn xét 2+1=3 cặp; điều kiện > luôn sai, nên không đổi chỗ.
Bài luyện
Điều gì có thể đổi theo dữ liệu đầu vào dù độ dài dãy giữ nguyên?
Vòng ngoài luôn n−1 lượt.
Số so sánh luôn n(n−1)/2.
Điều kiện > đúng hay sai tùy giá trị.
Công thức chỉ phụ thuộc n.
Lời giải
Hai dãy cùng độ dài có thể có số cặp sai thứ tự khác nhau, nên số đổi chỗ khác nhau.
Đang học