Cơ sở, hai lời gọi và bước trộn
```python
def mergeSort(A):
if len(A) <= 1:
return A
k = len(A) // 2
B = mergeSort(A[:k])
C = mergeSort(A[k:])
return merge(B, C)
```
Hàm dùng merge của bài trước. Với k=len(A)//2, A[:k] gồm các chỉ số 0 đến k−1; A[k:] gồm k đến cuối. Hai phần không chồng nhau và không bỏ sót phần tử. Nếu độ dài lẻ, hai phần hơn kém nhau một phần tử.
Cơ sở được kiểm trước khi chia nên dãy rỗng hoặc một phần tử không gọi tiếp. Sau khi hai lời gọi trả B,C đã sắp xếp, return merge(B,C) tạo kết quả của cả dãy.
Dãy trả về cần được giữ lại
Với A=[6,2,5,1], k=2. Hai phần [6,2] và [5,1] được sắp thành [2,6] và [1,5]; trộn để nhận [1,2,5,6].
```python
A = [6, 2, 5, 1]
B = mergeSort(A)
print(B)
```
B là [1,2,5,6], còn A vẫn là [6,2,5,1]. Chỉ gọi mergeSort(A) mà không giữ kết quả chưa làm A thay đổi. Bản này không sửa A; với dãy dài 0 hoặc 1, return A có thể trả chính đối tượng đầu vào, nên không khẳng định mọi lời gọi đều tạo một đối tượng mới.
Bài luyện
A có 5 phần tử, k=2. Hai lát cắt đúng cho mã trong bài là gì?
Hai phần chứa chỉ số 0,1 và2,3,4, không lặp hoặc thiếu.
Chỉ số 2 bị đưa vào cả hai phần.
Bỏ mất chỉ số 2.
Bỏ mất các phần tử ở hai đầu.
Lời giải
Lát cắt Python không lấy chỉ số kết thúc. A[:2] chứa 0,1; A[2:] chứa 2,3,4. Hai độ dài 2 và 3 phủ đủ dãy.
Bài luyện
A=[6,2,5,1], thực hiện B=mergeSort(A). Kết luận nào đúng?
Cả hai nửa được sắp và trộn đủ.
Hàm trả dãy đã trộn và không sửa dãy A.
Mã không ghi kết quả vào A.
Hàm có return trả kết quả.
Lời giải
Hai lát cắt được xử lí riêng, merge tạo dãy kết quả. Lệnh gán giữ kết quả vào B; không có thao tác sửa các phần tử của A.
Bài luyện
Vì sao phải kiểm len(A)<=1 trước khi chia?
Dãy độ dài lẻ vẫn chia thành hai phần lệch1.
Thuật toán cần cả hai nửa.
Đó là cơ sở giúp đệ quy kết thúc.
Dấu của số không liên quan cơ sở này.
Lời giải
Nếu dãy đã có không quá một phần tử, không cần chia và trộn thêm. Cơ sở trả ngay trước khi tạo các lời gọi nhỏ, giúp thuật toán kết thúc.
Đang học