TÀI LIỆU GIÁO KHOA CHUYÊN TIN HỌC (QUYỂN 2)

Tổng quan về giáo trình

Tài liệu giáo khoa chuyên tin học Quyển 2 là công trình học thuật được biên soạn dựa trên khung chương trình chuyên sâu môn Tin học dành cho các lớp chuyên 10, 11 và 12 do Bộ Giáo dục và Đào tạo ban hành. Sách do Giáo sư Hồ Sĩ Đàm chủ biên, cùng với sự tham gia của các tác giả Đỗ Đức Đông, Lê Minh Hoàng và Nguyễn Thanh Hùng, được Nhà xuất bản Giáo dục Việt Nam phát hành (mã số xuất bản: 349-2009/CXB/43-644/GD). Bộ sách bao gồm ba tập (Quyển 1, Quyển 2 và Quyển 3), trong đó Quyển 2 tập trung trực tiếp vào các vấn đề cốt lõi về kiểu dữ liệu trừu tượng, cấu trúc dữ liệu, giải thuật và phương pháp cài đặt chương trình tương ứng.

Mục tiêu đào tạo của giáo trình hướng tới việc cung cấp hệ thống lý thuyết cấu trúc dữ liệu chuẩn mực, rèn luyện kỹ năng phân tích độ phức tạp thuật toán và chuẩn hóa kỹ thuật lập trình thực nghiệm. Giáo trình được thiết kế nhằm phục vụ công tác giảng dạy của giáo viên và học tập của học sinh tại các trường Trung học phổ thông chuyên, trường Trung học cơ sở chuyên Tin học, đồng thời đóng vai trò tài liệu tham khảo cho sinh viên ngành Công nghệ thông tin tham dự các kỳ thi học thuật như Kỳ thi Học sinh giỏi Quốc gia, Quốc tế, Hội thi Tin học trẻ Toàn quốc, Olympic Tin học Sinh viên Toàn quốc và Kỳ thi Lập trình viên Quốc tế ACM/ICPC khu vực Đông Nam Á.

Cấu trúc mỗi chuyên đề trong sách tuân thủ mô hình sư phạm ba phần:

  1. Phần lý thuyết: Định nghĩa hình thức các khái niệm cơ bản, xác lập mô hình toán học và các thao tác nguyên thủy.
  2. Phần áp dụng: Trình bày phương pháp mô hình hóa bài toán thực tế, thuật toán xử lý và cài đặt chương trình cụ thể.
  3. Phần bài tập: Hệ thống hóa các bài toán mở rộng và bài tập nâng cao có định hướng nghiên cứu sâu.

Điểm đặc trưng của tài liệu là việc phân tích cấu trúc dữ liệu dưới cả hai góc độ phương pháp luận: kỹ thuật lập trình cấu trúc (Structural Programming) và kỹ thuật lập trình hướng đối tượng (Object-Oriented Programming), minh họa trực tiếp bằng mã nguồn Pascal/Object Pascal.


Nội dung kiến thức cốt lõi

                             KIỂU DỮ LIỆU TRỪU TƯỢNG VÀ CẤU TRÚC DỮ LIỆU
                                                  │
         ┌────────────────────────────────────────┼────────────────────────────────────────┐
         │                                        │                                        │
   CẤU TRÚC DANH SÁCH                      NGĂN XẾP & HÀNG ĐỢI                        CẤU TRÚC CÂY
         │                                        │                                        │
 ┌───────┴───────┐                        ┌───────┴───────┐                        ┌───────┴───────┐
 │               │                        │               │                        │               │
Mảng      Danh sách liên kết            Ngăn xếp       Hàng đợi               Cây tổng quát   Cây nhị phân
          - Nối đơn (Singly)            (Stack - LIFO) (Queue - FIFO)          - Mảng cha      - Suy biến
          - Nối kép (Doubly)              │               │                    - First/Sibling - Hoàn chỉnh
          - Nối vòng (Circular)           └───────┬───────┘                                    - Gần hoàn chỉnh
                                                  │                                            - Đầy đủ
                                          ỨNG DỤNG BIỂU THỨC                                   - Cây k-phân
                                          - Cây biểu thức
                                          - Tiền tố / Trung tố / Hậu tố (RPN)
                                          - Thuật toán Shunting-yard (Dijkstra)

Các chương và chủ đề chính

Nội dung trích xuất từ giáo trình tập trung vào Chuyên đề 6: Kiểu dữ liệu trừu tượng và Cấu trúc dữ liệu, bao gồm các khối kiến thức trọng tâm sau:

1. Cấu trúc danh sách (List)

Danh sách được định nghĩa là một tập hợp sắp thứ tự các phần tử có cùng kiểu dữ liệu $TElement$. Giáo trình khảo sát chi tiết các phương pháp biểu diễn và phân tích chi phí thời gian thực hiện:

  • Biểu diễn bằng mảng tĩnh một chiều ($a$): Sử dụng biến nguyên $n$ lưu trữ kích thước. Truy cập phần tử tại vị trí $p$ đạt độ phức tạp $\Theta(1)$. Phép chèn (Insert) và phép xóa (Delete) đòi hỏi thao tác dịch chuyển các phần tử kế tiếp, có thời gian thực hiện trong trường hợp tốt nhất là $\Theta(1)$, trường hợp xấu nhất và trung bình là $\Theta(n)$.
  • Danh sách nối đơn (Singly-linked list): Mỗi nút là một bản ghi $TNode$ gồm trường dữ liệu $info$ và trường liên kết $link$ (con trỏ $PNode$ trỏ tới nút kế tiếp, kết thúc bằng con trỏ $nil$). Con trỏ $head$ quản lý nút đầu tiên. Phép truy cập ngẫu nhiên mất thời gian trung bình $\Theta(n)$. Phép chèn và xóa nút đòi hỏi duyệt tìm nút liền trước, tiêu tốn thời gian trung bình $\Theta(n)$.
  • Danh sách nối kép (Doubly-linked list): Cấu trúc nút mở rộng với hai trường liên kết: con trỏ $next$ (trỏ tới nút kế tiếp) và con trỏ $prev$ (trỏ tới nút liền trước). Quản trị danh sách qua hai mốc $head$ và $tail$. Cho phép duyệt hai chiều và tối ưu hóa thao tác chèn/xóa tại một vị trí nút đã biết về thời gian $\Theta(1)$.
  • Danh sách nối vòng (Circular linked list): Bao gồm danh sách nối vòng đơn (nút cuối trỏ về nút đầu) và danh sách nối vòng kép (kết nối $head.prev \rightarrow tail$ và $tail.next \rightarrow head$), loại bỏ các trường hợp xử lý biên đặc biệt khi thao tác ở đầu danh sách.
Phương pháp biểu diễn Truy cập ngẫu nhiên Phép chèn phần tử Phép xóa phần tử
Mảng (Array) $\Theta(1)$ $\Theta(n)$ $\Theta(n)$
Danh sách nối đơn $\Theta(n)$ $\Theta(n)$ $\Theta(n)$
Danh sách nối kép $\Theta(n)$ $\Theta(1)^*$ $\Theta(1)^*$
Danh sách nối vòng đơn $\Theta(n)$ $\Theta(n)$ $\Theta(n)$
Danh sách nối vòng kép $\Theta(n)$ $\Theta(1)^*$ $\Theta(1)^*$
Cây (Tree) $\Theta(\log n)$ $\Theta(\log n)$ $\Theta(\log n)$

*Ghi chú: Độ phức tạp $\Theta(1)$ đối với danh sách nối kép đạt được khi đã xác định được vị trí con trỏ của nút cần thao tác.

2. Ngăn xếp (Stack) và Hàng đợi (Queue)

  • Ngăn xếp (Stack): Kiểu dữ liệu danh sách hoạt động theo nguyên tắc vào sau ra trước LIFO (Last In First Out). Gồm 6 thao tác cơ bản: Init (khởi tạo rỗng), IsEmpty (kiểm tra rỗng), IsFull (kiểm tra đầy), Get (đọc phần tử đỉnh $top$), Push (đẩy phần tử vào đỉnh), Pop (lấy phần tử khỏi đỉnh). Giáo trình trình bày hai kỹ thuật cài đặt: dùng mảng tĩnh và dùng danh sách nối đơn cấp phát động (loại bỏ giới hạn tĩnh của IsFull).
  • Hàng đợi (Queue): Kiểu dữ liệu danh sách hoạt động theo nguyên tắc vào trước ra trước FIFO (First In First Out). Quản lý qua hai chỉ số $front$ (vị trí lấy ra) và $rear$ (vị trí đẩy vào). Để khắc phục hiện tượng tràn mảng giả tạo khi các chỉ số tịnh tiến liên tục, giáo trình đưa ra giải pháp cài đặt hàng đợi trên danh sách vòng bằng mảng kết hợp phép toán số học đồng dư ($rear = (rear + 1) \pmod{max}$ và $front = (front + 1) \pmod{max}$), cùng kỹ thuật cài đặt bằng danh sách liên kết động qua hai con trỏ $front, rear$.
  • Hàng đợi hai đầu (Deque): Cấu trúc dữ liệu mở rộng cho phép thực hiện bốn thao tác chèn/xóa ở cả hai đầu danh sách (PushFront, PushBack, PopFront, PopBack).

3. Cấu trúc Cây (Tree) và Cây nhị phân (Binary Tree)

  • Khái niệm hình thức: Cây là cấu trúc phân cấp đệ quy gồm tập hợp hữu hạn các nút với một nút gốc ($root$). Các khái niệm cơ bản gồm: đường đi ($path$), độ dài đường đi, quan hệ cha-con ($parent$-$child$), tiền bối ($ancestor$), tiền bối thực sự ($proper\ ancestor$), hậu duệ ($descendant$), nút lá ($leaf$), nút nhánh ($branch$), độ sâu ($depth$), độ cao của nút và chiều cao của cây ($height$), rừng ($forest$), cây có thứ tự và không thứ tự.
  • Biểu diễn cây tổng quát: Biểu diễn bằng mảng nhãn liên kết tới nút cha ($parent$), hoặc biểu diễn bằng cấu trúc liên kết đa hướng con cả - em kề ($first\ child\ -\ next\ sibling$) với cấu trúc $TNode$ gồm ba con trỏ parent, first, sibling.
  • Phân loại cây nhị phân:
    • Cây nhị phân suy biến (Degenerate): Các nút nhánh chỉ có đúng một nút con (lệch trái, lệch phải, zíc-zắc), có chiều cao lớn nhất tương ứng với số nút.
    • Cây nhị phân hoàn chỉnh (Complete): Mọi nút lá ở cùng độ sâu $d$, mọi nút nhánh đều có hai con. Tổng số nút ở độ cao $h$ là $2^{h+1}-1$.
    • Cây nhị phân gần hoàn chỉnh (Nearly Complete): Chiều cao của cây $n$ nút đạt giá trị tối ưu $\lfloor \log_2 n \rfloor$.
    • Cây nhị phân đầy đủ (Full): Mọi nút nhánh đều có đúng hai nút con. Giáo trình chứng minh định lý: số nút lá luôn nhiều hơn số nút bậc 2 đúng 1 nút ($N_{leaf} = N_{deg2} + 1$).
  • Giải thuật duyệt cây nhị phân:
    • Duyệt tiền thứ tự (Preorder): Xử lý nút gốc $\rightarrow$ Duyệt nhánh trái $\rightarrow$ Duyệt nhánh phải.
    • Duyệt trung thứ tự (Inorder): Duyệt nhánh trái $\rightarrow$ Xử lý nút gốc $\rightarrow$ Duyệt nhánh phải.
    • Duyệt hậu thứ tự (Postorder): Duyệt nhánh trái $\rightarrow$ Duyệt nhánh phải $\rightarrow$ Xử lý nút gốc.
    • Phục hồi cấu trúc cây: Giáo trình xác lập nguyên lý cấu trúc cây nhị phân được khôi phục đơn định khi biết cặp thứ tự duyệt (Preorder + Inorder) hoặc (Postorder + Inorder).
          [ + ]                  Thứ tự duyệt cây biểu thức:
         /     \                 - Tiền tố (Preorder):  * + / 6 2 4 - 8 3
       [ * ]   [ - ]             - Trung tố (Inorder):   (6 / 2 + 4) * (8 - 3)
       /   \   /   \             - Hậu tố (Postorder):  6 2 / 4 + 8 3 - *
     [ / ] [4][8]  [3]
     /   \
   [6]   [2]

4. Ứng dụng xử lý biểu thức số học

  • Cây biểu thức: Biểu diễn biểu thức đại số bằng cây nhị phân đầy đủ (toán tử nằm ở nút nhánh, toán hạng nằm ở nút lá).
  • Ký pháp biểu thức:
    • Dạng tiền tố (Prefix / Polish Notation): Sinh ra từ phép duyệt tiền thứ tự.
    • Dạng trung tố (Infix): Sinh ra từ phép duyệt trung thứ tự, yêu cầu hệ thống dấu ngoặc để chỉ định thứ tự ưu tiên.
    • Dạng hậu tố (Postfix / Reverse Polish Notation - RPN): Do nhà lô-gic học Ba Lan Jan Łukasiewicz đề xuất năm 1920, sinh ra từ phép duyệt hậu thứ tự, cho phép tính toán đơn định không cần dấu ngoặc.
  • Giải thuật tính giá trị RPN: Sử dụng một Stack lưu trữ toán hạng; khi gặp toán tử, lấy hai phần tử khỏi ngăn xếp, thực hiện phép tính và đẩy kết quả trở lại ngăn xếp.
  • Thuật toán Shunting-yard (Xếp toa tàu): Do Edsger Dijkstra đề xuất năm 1960, sử dụng một Stack toán tử với bảng trọng số ưu tiên (Priority: *, / mức 2; +, - mức 1; ( mức 0) để chuyển đổi biểu thức từ Infix sang Postfix.

Kiến thức nền tảng được xây dựng

Giáo trình thiết lập nền tảng lý thuyết thông qua:

  1. Lý thuyết trừu tượng hóa dữ liệu: Phân tách ranh giới giữa mô hình toán học (Abstract Data Type) và cấu trúc dữ liệu vật lý (Data Structure) trong bộ nhớ.
  2. Kỹ thuật quản lý bộ nhớ con trỏ: Cơ chế cấp phát động (New), giải phóng tài nguyên (Dispose), và thao tác tái định tuyến liên kết con trỏ.
  3. Phân tích tiệm cận thời gian: Đánh giá thuật toán theo các trường hợp tốt nhất, xấu nhất và trung bình thông qua ký hiệu $\Theta$.

Kỹ năng phát triển

  • Kỹ năng phân tích và mô hình hóa: Chuyển đổi các bài toán thực tế (cấu trúc thư mục, gia phả, phân tích cú pháp số học, bài toán xếp toa tàu hỏa) thành mô hình danh sách, ngăn xếp, hàng đợi hoặc cây phân cấp.
  • Kỹ năng cài đặt giải thuật: Lập trình giải thuật đệ quy trên cây, phân tích chuỗi ký tự (Parsing), xử lý token biểu thức và lập trình cấu trúc danh sách liên kết.
  • Kỹ năng tối ưu hóa chương trình: Đóng gói chương trình con, thiết kế hàm nội tuyến (inline functions) và lựa chọn cấu trúc dữ liệu thích hợp để giảm độ phức tạp tính toán.

Phương pháp giảng dạy và học tập

Phương pháp tiếp cận sư phạm

Giáo trình áp dụng phương pháp tiếp cận từ bản chất cấu trúc đến cài đặt cơ chế. Mỗi chủ đề không dừng lại ở mức mô tả cú pháp ngôn ngữ mà phân tích sâu về cơ chế chiếm dụng bộ nhớ, sự đánh đổi (trade-off) giữa thời gian xử lý và dung lượng lưu trữ (ví dụ: so sánh mảng tĩnh truy cập $\Theta(1)$ nhưng chèn $\Theta(n)$ với danh sách liên kết chèn $\Theta(1)$ nhưng truy cập $\Theta(n)$).

         MÔ HÌNH TOÁN HỌC (ADT)
                   │
                   ▼
     CƠ CHẾ BỘ NHỚ & ĐỘ PHỨC TẠP
         (Mảng tĩnh vs. Biến động)
                   │
                   ▼
     CÀI ĐẶT THUẬT TOÁN & MÃ NGUỒN
    (Pascal / Object Pascal biên dịch)
                   │
                   ▼
     BÀI TOÁN THỰC THI & KIỂM THỬ
        (Sample Input -> Sample Output)

Bài tập và bài toán ứng dụng

Tài liệu cung cấp hệ thống bài tập đa dạng gắn liền với các kỳ thi chuyên môn:

  • Xử lý danh sách có thứ tự: Cài đặt các phép toán chèn, xóa, tìm kiếm trên danh sách số nguyên tăng dần; thuật toán trộn $k$ danh sách đã sắp xếp thành một danh sách duy nhất.
  • Đại số máy tính: Biểu diễn đa thức $P(x) = a_n x^{e_n} + \dots + a_0 x^{e_0}$ bằng danh sách nối đơn chứa cặp $(a_i, e_i)$ và xây dựng thuật toán cộng, nhân hai đa thức.
  • Xử lý số học lớn: Thực hiện phép toán cộng 1 trên số nhị phân $n$-bit lưu trữ dưới dạng danh sách liên kết đơn bằng giải thuật đệ quy.
  • Mô phỏng chuyển động hệ thống: Giải quyết bài toán hoán vị toa tàu trên sơ đồ ray nhánh chữ Y thông qua cơ chế Stack và Queue.
  • Tái thiết cây cấu trúc: Khôi phục cấu trúc cây nhị phân dựa trên các vector duyệt Preorder, Inorder và Postorder.

Phương pháp kiểm thử và tự học

Giáo trình cung cấp các chương trình hoàn chỉnh bằng Object Pascal (chế độ biên dịch {$MODE OBJFPC}) kèm theo bộ dữ liệu mẫu (Sample Input / Sample Output), ví dụ:

  • Đầu vào RPN: 6 2 / 4 + 8 3 - *
  • Kết quả: 35.0000
  • Đầu vào Infix: (6 / 2 + 4) * (8 - 3)
  • Đầu ra RPN: 6 2 / 4 + 8 3 - *

Người học có thể tự kiểm tra tính đúng đắn của giải thuật thông qua việc biên dịch và chạy thử nghiệm trực tiếp trên máy tính.


Điểm nổi bật và cập nhật

  1. Chuẩn hóa hệ thống thuật ngữ chuyên ngành: Sách sử dụng hệ thống thuật ngữ chuẩn xác trong khoa học máy tính: Abstract Data Type, Singly/Doubly/Circular Linked List, LIFO, FIFO, Degenerate/Complete/Full Binary Tree, Preorder/Inorder/Postorder Traversal, Shunting-yard Algorithm.
  2. Tính sư phạm trong thiết kế mã nguồn: Mã nguồn minh họa được chuẩn hóa theo cấu trúc module rõ ràng. Các thao tác nguyên thủy (Push, Pop, Get, Init, IsEmpty, IsFull, Priority, ProcessToken, Parsing) được tách biệt thành các chương trình con độc lập, thuận tiện cho việc gỡ rối và chuyển đổi nền tảng lập trình.
  3. Gắn liền với lịch sử phát triển khoa học tính toán: Giáo trình trích dẫn nguồn gốc học thuật của các giải thuật nền tảng, bao gồm công trình về logic học của Jan Łukasiewicz (1920) và thuật toán phân tích cú pháp của Edsger Dijkstra (1960), giúp người học hiểu rõ bối cảnh và lý do ra đời của các cấu trúc dữ liệu.

Đối tượng sử dụng giáo trình

  • Học sinh khối THPT chuyên Tin học (Lớp 10, 11, 12): Sử dụng làm tài liệu học tập chính khóa theo chương trình chuyên sâu của Bộ Giáo dục và Đào tạo, phục vụ ôn luyện các kỳ thi chọn học sinh giỏi cấp Tỉnh, cấp Quốc gia và Quốc tế.
  • Học sinh khối THCS chuyên Tin học: Tài liệu bồi dưỡng sớm các chuyên đề cấu trúc dữ liệu và giải thuật nâng cao tham gia Hội thi Tin học trẻ.
  • Sinh viên chuyên ngành Công nghệ thông tin / Khoa học máy tính: Tài liệu ôn tập nền tảng cấu trúc dữ liệu và giải thuật, phục vụ các kỳ thi Olympic Tin học Sinh viên Toàn quốc và Kỳ thi Lập trình Quốc tế ACM/ICPC.
  • Giáo viên và Huấn luyện viên: Giáo trình tham khảo phục vụ xây dựng bài giảng chuyên đề, thiết kế giáo án và biên soạn ngân hàng đề thi học thuật.
  • Điều kiện tiên quyết: Người học cần có kiến thức nền tảng về lập trình cơ sở (cú pháp lệnh, mảng, kiểu bản ghi, chương trình con) và các khái niệm toán học rời rạc cơ bản.

Câu hỏi thường gặp

1. Giáo trình này phù hợp với đối tượng nào?

Giáo trình được thiết kế chuyên biệt cho học sinh các lớp chuyên Tin học (THCS, THPT), sinh viên ngành Công nghệ thông tin định hướng lập trình thi đấu và giáo viên tham gia bồi dưỡng học sinh giỏi các cấp.

2. Cần chuẩn bị kiến thức nền tảng nào trước khi học?

Người học cần nắm vững kỹ thuật lập trình cơ bản (biến, rẽ nhánh, vòng lặp, mảng, hàm, thủ tục), cú pháp ngôn ngữ lập trình Pascal hoặc tương đương, cùng tư duy toán logic sơ cấp.

3. Điểm khác biệt của giáo trình so với sách tin học phổ thông đại trà là gì?

Tài liệu tập trung vào các chuyên đề chuyên sâu, phân tích bản chất kiểu dữ liệu trừu tượng, phân tích độ phức tạp thời gian tiệm cận ($\Theta$), đi sâu vào kỹ thuật quản lý bộ nhớ động và cung cấp các giải thuật kinh điển (Dijkstra, Łukasiewicz) phục vụ thi đấu học thuật.

4. Làm sao để tự học hiệu quả với tài liệu này?

Người học nên tuân thủ trình tự: nghiên cứu định nghĩa lý thuyết $\rightarrow$ vẽ mô hình bộ nhớ của cấu trúc dữ liệu $\rightarrow$ viết mã nguồn theo mã giả $\rightarrow$ biên dịch và kiểm thử với các bộ dữ liệu mẫu $\rightarrow$ giải quyết toàn bộ hệ thống bài tập mở rộng ở cuối mỗi chuyên đề.

5. Mã nguồn trong giáo trình sử dụng ngôn ngữ lập trình nào?

Giáo trình sử dụng mã giả kết hợp ngôn ngữ Pascal / Object Pascal chuẩn ({$MODE OBJFPC}), đồng thời diễn giải nguyên lý tổng quát để người học dễ dàng chuyển đổi sang các ngôn ngữ khác như C++ hoặc Java.


Kết luận

Tài liệu giáo khoa chuyên tin học Quyển 2 do GS. Hồ Sĩ Đàm chủ biên là tài liệu học thuật chuẩn mực, hệ thống hóa toàn diện các kiến thức về kiểu dữ liệu trừu tượng, cấu trúc dữ liệu động và thuật toán xử lý dữ liệu phân cấp. Giáo trình thiết lập lộ trình học tập logic từ các cấu trúc tuyến tính (Danh sách, Ngăn xếp, Hàng đợi) đến phi tuyến (Cây tổng quát, Cây nhị phân, Cây $k$-phân) và các giải thuật phân tích cú pháp biểu thức kinh điển. Đây là tài liệu phục vụ đắc lực cho công tác giảng dạy, học tập và bồi dưỡng nhân tài trong các kỳ thi học sinh giỏi và Olympic Tin học.