Mảng tĩnh vs mảng động
Mảng (array) là cấu trúc dữ liệu cơ bản và quan trọng nhất — gần như mọi thứ khác xây trên nó.
Bạn sẽ hiểu vì sao lấy phần tử thứ i của mảng là tức thì (O(1)), và khác biệt giữa mảng
tĩnh với m ảng động.
1. Trực quan: dãy ô tủ đánh số liền nhau
Tưởng tượng một dãy ô tủ đặt sát nhau, đánh số 0, 1, 2, 3... Mảng chính là vậy: các phần tử nằm liền kề nhau trong bộ nhớ, mỗi ô có một chỉ số (index).
chỉ số: 0 1 2 3 4
┌─────┬─────┬─────┬─────┬─────┐
A = │ 10 │ 20 │ 30 │ 40 │ 50 │
└─────┴─────┴─────┴─────┴─────┘
địa chỉ: 100 104 108 112 116 (mỗi ô cách nhau đều nhau)
2. Vì sao A[i] là O(1)? (chìa khoá của mảng)
Vì các ô liền kề và đều nhau, máy tính địa chỉ ô thứ i bằng một phép tính:
địa_chỉ(A[i]) = địa_chỉ_đầu + i × (kích thước mỗi ô)
Không cần dò từ đầu — nhảy thẳng tới đúng ô. Lấy A[0] hay A[1000000] đều một bước như nhau.
Đây là siêu năng lực của mảng: truy cập ngẫu nhiên tức thì.
Bước qua để thấy mọi truy cập đều là 1 bước, dù ở vị trí nào:
3. Mảng TĨNH vs mảng ĐỘNG
Mảng tĩnh: kích thước cố định khi tạo. Nhanh, gọn, nhưng không thêm được quá sức chứa.
Hay gặp ở C, Java (int[]).
Mảng động: tự lớn lên khi đầy. Hầu hết ngôn ngữ hiện đại dùng nó: Python list, Java
ArrayList, JS Array. Thêm phần tử (append) là amortized O(1) — nhớ lại
bài 1.2.6: khi đầy thì nhân đôi sức chứa, trung bình vẫn rẻ.
A = [1, 2, 3] # mang dong trong Python
A.append(4) # tu lon len -> [1, 2, 3, 4]
4. Code mẫu (chạy thật)
5. Mặt trái: thêm/xóa GIỮA mảng tốn O(n)
Vì các ô phải liền kề, chèn/xóa ở giữa buộc phải dịch mọi phần tử phía sau → O(n). Đây là điểm yếu của mảng (ta sẽ học kỹ ở bài tiếp theo và thấy danh sách liên kết khắc phục ra sao).
6. Mẫu nhận diện
- Cần truy cập nhanh theo vị trí, dữ liệu ít thay đổi giữa chừng → dùng mảng.
- Cần thêm/xóa liên tục ở giữa/đầu → mảng tốn O(n) mỗi lần, cân nhắc cấu trúc khác.
- Đa số bài DSA bắt đầu từ mảng — nắm chắc nó trước.
7. 🎮 Trò chơi: Hiểu mảng
8. Quiz kiểm tra nhanh
9. Hoàn thành
…☑️ Tiếp theo: 2.1.2 — Thao tác cơ bản & độ phức tạp (nhìn rõ vì sao chèn đầu tốn O(n)).