Tổng quan về giáo trình
Tài liệu bài giảng Data Structure and Algorithms (mã môn học: CO2003), cụ thể là Chapter 5: Stack and Queue, được biên soạn bởi TS. Nguyễn Đức Dũng (Duc Dung Nguyen, PhD. - Khoa Khoa học và Kỹ thuật Máy tính, Trường Đại học Bách Khoa TP.HCM - HCMUT). Môn học Cấu trúc dữ liệu và Giải thuật giữ vị trí nền tảng cốt lõi trong chương trình đào tạo kỹ sư ngành Khoa học Máy tính và Kỹ thuật Máy tính, cung cấp các nguyên lý tổ chức dữ liệu và thiết kế thuật toán xử lý dữ liệu có hiệu năng tối ưu.
Mục tiêu học tập của học phần (Learning Outcomes) được chuẩn hóa từ L.1 đến L.6:
- L.1: Mô tả các khái niệm về danh sách mảng (array list), danh sách liên kết (linked list đơn, đôi, đa liên kết), ngăn xếp (stack), hàng đợi (queue) và hàng đợi vòng (circular queue).
- L.2: Biểu diễn cấu trúc lưu trữ bằng mã giả (pseudocode) cho các cấu trúc danh sách, ngăn xếp và hàng đợi.
- L.3: Liệt kê và mô tả bằng mã giả các phương thức thao tác cần thiết trên danh sách, ngăn xếp và hàng đợi.
- L.4: Cài đặt hoàn chỉnh danh sách, ngăn xếp và hàng đợi bằng ngôn ngữ C/C++.
- L.5: Ứng dụng danh sách, ngăn xếp, hàng đợi để giải quyết bài toán thực tế; phân tích và lựa chọn hình thức cài đặt phù hợp (mảng hay danh sách liên kết).
- L.6: Phân tích độ phức tạp thuật toán bằng ký hiệu Big-O, xây dựng chương trình thực nghiệm để đánh giá hiệu năng và triển khai các thuật toán đệ quy trên cấu trúc danh sách, cây (tree), heap, tìm kiếm và đồ thị (graph).
Bài giảng tiếp cận theo trình tự logic chặt chẽ: xuất phát từ lý thuyết phân loại danh sách tuyến tính, trực quan hóa cấu trúc dữ liệu qua sơ đồ hoạt động, mô hình hóa giải thuật bằng mã giả và kết thúc bằng việc hiện thực hóa qua ngôn ngữ C++ với kỹ thuật lập trình mẫu (template).
Nội dung kiến thức cốt lõi
Các chương và chủ đề chính
Tài liệu Chương 5 tập trung vào hai cấu trúc dữ liệu trừu tượng tuyến tính dạng hạn chế (restricted linear lists) với các phân đoạn nội dung chính:
- Các thao tác cơ bản trên ngăn xếp (Basic operations of Stacks): Phân biệt giữa danh sách tổng quát (General list - không hạn chế vị trí thao tác) và danh sách hạn chế (Restricted list - chỉ thao tác tại các đầu mút). Định nghĩa cấu trúc Stack hoạt động theo nguyên lý LIFO (Last In - First Out).
- Cài đặt ngăn xếp (Implementation of Stacks): Triển khai ngăn xếp bằng hai phương pháp lưu trữ: danh sách liên kết đơn (Linked-list implementation) và mảng động (Array-based implementation).
- Ứng dụng của ngăn xếp (Applications of Stack): Khảo sát các bài toán ứng dụng ngăn xếp trong tính toán biểu thức, quản lý bộ nhớ hàm và giải thuật đệ quy.
- Các thao tác cơ bản trên hàng đợi (Basic operations of Queues): Định nghĩa cấu trúc Queue hoạt động theo nguyên lý FIFO (First In - First Out) và hàng đợi vòng (Circular queue).
- Cài đặt hàng đợi (Implementation of Queue): Cài đặt cấu trúc lưu trữ và các hàm giao tiếp cho hàng đợi dựa trên mảng và danh sách liên kết.
- Ứng dụng của hàng đợi (Applications of Queue): Ứng dụng trong điều phối tiến trình, bộ đệm dữ liệu và giải thuật duyệt đồ thị theo chiều rộng (BFS).
Trong toàn bộ chương trình môn học CO2003, nội dung Chương 5 đóng vai trò cầu nối chuyển tiếp từ cấu trúc dữ liệu tuyến tính cơ bản (Array, Linked List) sang các cấu trúc dữ liệu phi tuyến tính phức tạp hơn ở các chương tiếp theo như Cây (Tree), Cây ưu tiên (Heap) và Đồ thị (Graph).
Kiến thức nền tảng được xây dựng
- Cơ chế LIFO (Last In - First Out): Phần tử được nạp vào cuối cùng sẽ là phần tử đầu tiên được lấy ra khỏi cấu trúc. Mọi thao tác chèn và xóa đều bị giới hạn tại một vị trí duy nhất gọi là đỉnh ngăn xếp (
top).
- Cấu trúc dữ liệu trừu tượng (ADT) của Stack:
- Thao tác cơ sở:
Push (nạp phần tử vào đỉnh), Pop (lấy và loại bỏ phần tử ở đỉnh), Top / GetStackTop (truy xuất giá trị phần tử ở đỉnh mà không thay đổi ngăn xếp).
- Thao tác mở rộng:
IsEmpty (kiểm tra ngăn xếp rỗng), IsFull (kiểm tra ngăn xếp đầy), GetSize (đếm số lượng phần tử hiện có), Clear / destroyStack (hủy toàn bộ phần tử và giải phóng bộ nhớ).
- Kiểm soát trạng thái lỗi: Lỗi tràn ngăn xếp (Stack Overflow) khi thực hiện
Push vào ngăn xếp đã đầy dung lượng; lỗi rỗng ngăn xếp (Stack Underflow) khi thực hiện Pop hoặc Top trên ngăn xếp không chứa phần tử.
- Mô hình tổ chức bộ nhớ:
- Mô hình liên kết (Linked-list): Lưu trữ động phân tán thông qua cấu trúc nút
Node gồm trường data và con trỏ next. Trạng thái ngăn xếp được quản trị thông qua con trỏ đỉnh top và biến đếm kích thước count.
- Mô hình mảng tuần tự (Array-based): Lưu trữ vùng nhớ liên tục thông qua mảng động
storage với chỉ số quản lý top (khởi tạo ở giá trị -1) và giới hạn kích thước tối đa capacity.
Kỹ năng phát triển
- Kỹ năng thiết kế mã giả: Xây dựng giải thuật chuẩn tắc độc lập với ngôn ngữ lập trình, xác định rõ điều kiện tiên quyết (Pre-condition) và kết quả hậu nghiệm (Post-condition) cho từng hàm (
createStack, pushStack, popStack, stackTop, destroyStack, isEmpty).
- Kỹ năng lập trình hệ thống bằng C++:
- Ứng dụng kỹ thuật generic programming thông qua
template <class ItemType> để xây dựng cấu trúc dữ liệu tổng quát cho mọi kiểu dữ liệu.
- Quản lý vòng đời đối tượng và bộ nhớ động thông qua Constructor, Destructor, các toán tử
new, delete và delete[].
- Cài đặt cơ chế kiểm soát ngoại lệ bằng cách phát sinh chuỗi thông báo lỗi (
throw string("Stack is overflow"), throw string("Stack is empty")).
- Kỹ năng phân tích hiệu năng: Sử dụng ký hiệu Big-O để đánh giá độ phức tạp thuật toán của các thao tác cơ bản ($O(1)$ cho
Push, Pop, Top, IsEmpty trên cả hai mô hình cài đặt).
Phương pháp giảng dạy và học tập
Tài liệu áp dụng phương pháp sư phạm đa tầng (multi-tiered pedagogical framework), kết hợp giữa biểu diễn hình học, giải thuật hình thức và triển khai mã nguồn:
- Khái niệm và cơ chế hoạt động: Phân tích bản chất của cấu trúc tuyến tính hạn chế so với danh sách tổng quát.
- Trực quan hóa qua sơ đồ trạng thái: Sử dụng các hình vẽ minh họa từng bước dịch chuyển con trỏ và biến đổi cấu trúc:
- Figure 1 & 2: Trạng thái
Push thành công và Push Overflow.
- Figure 3 & 4: Trạng thái
Pop thành công và Pop Underflow.
- Figure 5 & 6: Trạng thái
Top thành công và Top Underflow.
- Mô hình hóa bằng mã giả chuẩn tắc: Định nghĩa giải thuật với các tham số truyền tham chiếu (
ref stack, ref dataOut) hoặc truyền giá trị (val data).
- Hiện thực hóa mã nguồn C++: Cung cấp cấu trúc lớp hoàn chỉnh (
template <class List_ItemType> class Stack và class ArrayStack).
- Thực thi và đánh giá kết quả: Minh họa qua hàm
main() với các thao tác nạp dữ liệu tuần tự (Push(7), Push(9), Push(10), Push(8)), in kiểm tra qua console (Print2Console()), rút trích phần tử (Pop()) và giải phóng đối tượng.
Điểm nổi bật và cập nhật
- Tính tổng quát hóa cao (Generic Programming): Việc ứng dụng mẫu lớp (Class Templates) trong C++ giúp các cấu trúc
Node và Stack có khả năng tái sử dụng linh hoạt với nhiều kiểu dữ liệu nguyên thủy hoặc đối tượng phức tạp mà không cần chỉnh sửa mã nguồn cốt lõi.
- So sánh đối chiếu trực tiếp hai kiến trúc lưu trữ:
| Tiêu chí so sánh |
Cài đặt bằng danh sách liên kết (Stack) |
Cài đặt bằng mảng (ArrayStack) |
| Cơ chế cấp phát |
Động từng nút (new Node) khi gọi Push |
Khối liên tục cố định theo capacity |
| Giới hạn dung lượng |
Phụ thuộc bộ nhớ khả dụng của hệ thống |
Bị giới hạn cứng bởi tham số capacity |
| Chi phí bộ nhớ phụ |
Tốn thêm bộ nhớ cho con trỏ next ở mỗi node |
Không tốn con trỏ, nhưng có thể lãng phí mảng chưa dùng hết |
Độ phức tạp Push/Pop |
$O(1)$ |
$O(1)$ |
| Hiện tượng tràn dữ liệu |
Xảy ra khi hệ thống hết bộ nhớ khả dụng |
Xảy ra khi chỉ số top == capacity - 1 |
- Quản trị an toàn bộ nhớ: Mã nguồn bài giảng cung cấp đầy đủ giải thuật dọn dẹp bộ nhớ trong hàm hủy (
~Stack(), ~ArrayStack(), hàm Clear()), duyệt tuần tự từng nút để thu hồi tài nguyên tránh rò rỉ bộ nhớ (memory leaks).
Đối tượng sử dụng giáo trình
- Sinh viên đại học: Sinh viên năm thứ 2 chuyên ngành Khoa học Máy tính, Kỹ thuật Máy tính, Hệ thống Thông tin, Kỹ thuật Phần mềm tham gia học phần Cấu trúc dữ liệu và Giải thuật (CO2003).
- Yêu cầu kiến thức tiên quyết (Prerequisites):
- Nắm vững kiến thức lập trình cơ bản và nâng cao với ngôn ngữ C/C++.
- Hiểu rõ cơ chế quản lý con trỏ (pointers), địa chỉ vùng nhớ, phân vùng Heap/Stack và cấp phát động (
new/delete).
- Nắm được các cấu trúc điều khiển cơ bản (tuần tự, rẽ nhánh, lặp) và phương pháp đánh giá thời gian chạy bằng ký hiệu hàm toán học.
- Giảng viên và người nghiên cứu: Sử dụng làm đề cương bài giảng chuẩn, khung thực hành bài tập lớn (assignments/labs) và làm tài liệu tham khảo để xây dựng các giải thuật nâng cao.
Câu hỏi thường gặp
1. Tài liệu này phù hợp với đối tượng nào?
Tài liệu được biên soạn phục vụ sinh viên khối ngành Công nghệ thông tin và Kỹ thuật máy tính tại Trường Đại học Bách Khoa TP.HCM (mã môn CO2003) cùng những người học cần nắm vững bản chất cài đặt cấu trúc dữ liệu mức hệ thống.
2. Cần chuẩn bị kiến thức nền tảng nào trước khi học nội dung này?
Người học cần hoàn thành học phần Nhập môn lập trình / Kỹ thuật lập trình C++, nắm vững cú pháp struct/class, kỹ thuật truyền tham chiếu, thao tác con trỏ và quản trị bộ nhớ động.
3. Ngăn xếp cài đặt bằng danh sách liên kết và mảng khác nhau như thế nào?
Cài đặt bằng danh sách liên kết cho phép mở rộng kích thước linh hoạt theo bộ nhớ hệ thống nhưng tốn thêm bộ nhớ lưu con trỏ next. Cài đặt bằng mảng tối ưu về định vị ô nhớ cục bộ nhưng đòi hỏi phải xác định kích thước capacity cố định trước khi khởi tạo.
4. Phương pháp tự học nội dung này như thế nào để đạt hiệu quả cao?
Người học nên kết hợp đọc hiểu sơ đồ trạng thái (Figures 1–6), viết lại giải thuật bằng mã giả, sau đó tự tay lập trình lại các lớp Stack và ArrayStack trên C++, kiểm thử đầy đủ các trường hợp biên như ngăn xếp rỗng hoặc ngăn xếp đầy.
5. Những thao tác cơ bản nào bắt buộc phải có của cấu trúc Stack?
Các thao tác bắt buộc gồm: khởi tạo ngăn xếp (Stack() / createStack), chèn phần tử vào đỉnh (Push), rút phần tử khỏi đỉnh (Pop), xem phần tử ở đỉnh (GetStackTop / Top), kiểm tra rỗng (IsEmpty) và giải phóng ngăn xếp (Clear / Destructor).
Kết luận
Bài giảng Chapter 5: Stack and Queue thuộc môn học Data Structure and Algorithms [CO2003] của Trường Đại học Bách Khoa TP.HCM cung cấp đầy đủ nền tảng lý thuyết và kỹ năng cài đặt thực tế cho hai cấu trúc dữ liệu tuyến tính hạn chế chuẩn tắc.
Việc nắm vững cơ chế vận hành LIFO/FIFO, kỹ thuật mã hóa C++ Template và kỹ năng phân tích thuật toán qua Big-O là bước chuẩn bị bắt buộc để người học tiếp cận các chủ đề tiếp theo trong chương trình đào tạo gồm Cấu trúc Cây (Binary Trees, AVL Trees), Hàng đợi ưu tiên (Heap), Giải thuật tìm kiếm và Cấu trúc Đồ thị (Graphs).