Phân tích học thuật và Tổng quan nội dung: Cây (Trees) trong Cấu trúc Dữ liệu và Giải thuật

Tài liệu học thuật được phân tích dựa trên bài giảng Chương 7: Cây (Chapter 7: Trees) thuộc học phần Cấu trúc dữ liệu và Giải thuật (Data Structures and Algorithms) do TS. Nguyễn Hồ Mẫn Răng, Khoa Khoa học và Kỹ thuật Máy tính, Trường Đại học Bách Khoa – ĐHQG-HCM (Faculty of Computer Science and Engineering, University of Technology, VNU-HCM) biên soạn.

Dưới đây là phần mô tả thư mục chi tiết, phân tích cấu trúc, phương pháp luận và nội dung kiến thức cốt lõi được trích xuất từ tài liệu.


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

Môn học và vị trí trong chương trình đào tạo

Học phần Cấu trúc dữ liệu và Giải thuật (DSA) là môn học cơ sở ngành cốt lõi trong chương trình đào tạo kỹ sư và cử nhân ngành Khoa học Máy tính và Kỹ thuật Máy tính. Nội dung Chương 7: Cây (Trees) giữ vị trí bản lề, đánh dấu bước chuyển tiếp phương pháp luận từ việc tổ chức dữ liệu dạng tuyến tính (danh sách liên kết, mảng, ngăn xếp, hàng đợi) sang cấu trúc dữ liệu phi tuyến tính có tính phân cấp (hierarchical structures). Kiến thức chương này tạo tiền đề trực tiếp cho các chủ đề nâng cao như cấu trúc chỉ mục cơ sở dữ liệu, phân tích cú pháp trong trình biên dịch và các thuật toán đồ thị.

Mục tiêu học tập (Learning Outcomes)

Chương học được xây dựng nhằm đáp ứng các chuẩn đầu ra cụ thể:

  • L.1: Mô tả và phân biệt các khái niệm cấu trúc cây: cây nhị phân (binary tree), cây nhị phân hoàn chỉnh (complete binary tree), cây cân bằng (balanced binary tree), cây AVL (AVL tree), cây nhiều nhánh (multi-way tree).
  • L.2 & L.3: Mô tả cấu trúc lưu trữ của cây và các phương thức xử lý dữ liệu liên quan thông qua mã giả (pseudocode).
  • L.4 & L.5: Xác định tầm quan trọng của đặc tính cân bằng trong cây; nhận diện các trường hợp cây AVL và B-tree bị mất cân bằng, thực hiện các thao tác cân bằng từng bước bằng sơ đồ minh họa.
  • L.6 & L.7: Hiện thực hóa cây nhị phân và cây AVL bằng ngôn ngữ lập trình C/C++; ứng dụng cây vào giải quyết các bài toán thực tế, đặc biệt là kỹ thuật tìm kiếm.
  • L.8 & chuẩn phân tích: Phân tích độ phức tạp tính toán bằng ký hiệu Big-O ($O$), xây dựng chương trình thử nghiệm để đánh giá hiệu năng các phương thức trên cấu trúc cây, đồng thời phát triển giải thuật đệ quy cho các cấu trúc danh sách, cây, heap, tìm kiếm và đồ thị.

Cấu trúc và cách tiếp cận

Tài liệu được phân chia thành 4 phân khu lý thuyết chính:

  1. Khái niệm cơ bản về cây (Basic Tree Concepts)
  2. Cây nhị phân (Binary Trees)
  3. Cây biểu thức (Expression Trees)
  4. Cây tìm kiếm nhị phân (Binary Search Trees)

Cách tiếp cận của giáo trình đi từ hình thức hóa toán học các khái niệm trừu tượng, mô hình hóa cấu trúc dữ liệu trên bộ nhớ, đến quy chuẩn giải thuật bằng mã giả và phân tích độ phức tạp tiệm cận.

Điểm đặc sắc của giáo trình

Tài liệu giảng dạy có tính chuẩn hóa cao về mặt thuật toán. Các thao tác duyệt cây, tìm kiếm, tính toán chỉ số cân bằng đều được biểu diễn song song giữa mô hình trực quan (đồ họa cây), mô hình vật lý (bộ nhớ mảng/con trỏ) và mã giả thuật toán có điều kiện tiền/hậu (Pre/Post conditions) rõ ràng.


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

Các chủ đề chính trong Chương 7

1. Khái niệm cơ bản về Cây (Basic Tree Concepts)

  • Định nghĩa: Cây là một tập hợp hữu hạn các phần tử gọi là nút (nodes) và một tập hợp hữu hạn các đường có hướng gọi là nhánh (branches) dùng để kết nối các nút.
  • Bậc và Nhánh:
    • Bậc của một nút (Degree): Tổng số nhánh liên kết với nút đó.
    • Nhánh vào (Indegree branch): Nhánh có hướng đi vào nút. Gốc (Root) là nút duy nhất có $\text{indegree} = 0$. Các nút còn lại có $\text{indegree} = 1$.
    • Nhánh ra (Outdegree branch): Nhánh có hướng đi ra khỏi nút ($\text{outdegree} \ge 0$).
  • Thuật ngữ phân loại nút:
    • Nút gốc (Root): Nút đầu tiên của cây, không có nhánh vào.
    • Nút lá (Leaf): Nút có $\text{outdegree} = 0$ (không có nút con).
    • Nút nội (Internal node): Nút không phải là gốc và không phải là lá. Nút nội đồng thời là nút con của một nút khác và là nút cha của các nút phía dưới.
    • Nút cha (Parent) & Nút con (Child): Nút cha có $\text{outdegree} > 0$; nút con có $\text{indegree} = 1$.
    • Nút anh em (Siblings): Hai hoặc nhiều nút có cùng một nút cha.
    • Tổ tiên (Ancestor) & Hậu duệ (Descendent): Tổ tiên là mọi nút nằm trên đường đi từ gốc đến nút chỉ định; hậu duệ là mọi nút nằm trên đường đi từ nút chỉ định đến các lá.
  • Các thông số hình học:
    • Đường đi (Path): Chuỗi các nút kế tiếp nhau qua các nhánh.
    • Mức của nút (Level): Khoảng cách từ gốc đến nút đó (Gốc ở Mức 0; các nút anh em luôn ở cùng một mức).
    • Chiều cao của cây (Height): Bằng mức của nút lá nằm trên đường đi dài nhất tính từ gốc cộng thêm 1.
    • Cây con (Subtree): Mọi cấu trúc liên thông bên dưới một nút chỉ định.
  • Phương pháp biểu diễn cây:
    • Sơ đồ tổ chức (organization chart).
    • Danh sách thụt lề (indented list).
    • Danh sách lồng ngoặc (parenthetical listing, ví dụ: a(b(e f) c d(g h i))).
    • Đồ thị nút - nhánh.

2. Cây nhị phân và Cấu trúc lưu trữ (Binary Trees)

  • Định nghĩa: Cây nhị phân là cây rỗng hoặc gồm một nút gốc liên kết với hai cây con nhị phân phân biệt: cây con bên trái (Left subtree) và cây con bên phải (Right subtree). Một nút không được phép có quá 2 cây con.
  • Các thuộc tính định lượng:
    • Với cây chứa $N$ nút:
      • Chiều cao tối thiểu: $H_{min} = \lfloor \log_2 N \rfloor + 1 = \lceil \log_2 (N + 1) \rceil$.
      • Chiều cao tối đa: $H_{max} = N$.
    • Với cây có chiều cao $H$:
      • Số nút tối thiểu: $N_{min} = H$.
      • Số nút tối đa: $N_{max} = 2^H - 1$.
  • Đặc tính cân bằng (Balance):
    • Hệ số cân bằng $B$ của nút: $B = H_L - H_R$ (chiều cao cây con trái trừ chiều cao cây con phải).
    • Cây cân bằng có $B \in {-1, 0, 1}$ tại mọi nút và các cây con chênh lệch chiều cao không quá 1.
  • Phân loại:
    • Cây nhị phân hoàn chỉnh (Complete tree): Đạt số nút tối đa $N = 2^H - 1$, mức cuối cùng được lấp đầy toàn bộ.
    • Cây gần hoàn chỉnh (Nearly complete tree): $H = \lfloor \log_2 N \rfloor + 1$, các nút ở mức cuối cùng được điền liên tục từ phía bên trái.
  • Hiện thực hóa cấu trúc dữ liệu:
    • Dạng liên kết (Linked implementation): Khai báo kiểu bản ghi node gồm trường dữ liệu dataType data (gồm key và các trường tin) cùng hai con trỏ left và right. Cấu trúc binaryTree quản lý một con trỏ root.
    • Dạng mảng (Array-based implementation): Biểu diễn tuyến tính các phần tử từ chỉ số $0, 1, 2, \dots$; phù hợp tối ưu cho cây hoàn chỉnh hoặc gần hoàn chỉnh nhằm tránh lãng phí vùng nhớ rỗng.

3. Các thuật toán duyệt cây nhị phân (Binary Tree Traversals)

Tài liệu quy định hai hướng tiếp cận duyệt cây:

Phương pháp duyệt Phân loại Thứ tự xử lý Giải thuật mã giả (Tóm tắt logic)
Duyệt theo chiều sâu (Depth-first traversal) Tiền tự (Preorder) Nút $\to$ Trái $\to$ Phải (NLR) if root not null: process(root); preOrder(root->left); preOrder(root->right)
Trung tự (Inorder) Trái $\to$ Nút $\to$ Phải (LNR) if root not null: inOrder(root->left); process(root); inOrder(root->right)
Hậu tự (Postorder) Trái $\to$ Phải $\to$ Nút (LRN) if root not null: postOrder(root->left); postOrder(root->right); process(root)
Duyệt theo chiều rộng (Breadth-first traversal) Theo mức (Level-order) Từng tầng từ trên xuống, từ trái qua phải Khởi tạo bfQueue. Đưa root vào hàng đợi. Lặp khi queue chưa rỗng: lấy nút ra process(), đẩy left và right vào hàng đợi.

4. Cây biểu thức (Expression Trees)

  • Cấu trúc: Mỗi nút lá chứa một toán hạng (operand); nút gốc và các nút nội chứa toán tử (operator); các cây con biểu diễn các biểu thức con (sub-expressions).
  • Mã giả ánh xạ dạng biểu thức qua các phép duyệt:
    • Biểu thức trung tố (Infix): Duyệt trung tự có bổ sung dấu ngoặc đơn để bảo toàn thứ tự ưu tiên toán tử:
      Algorithm infix(val tree <pointer>)
        if tree not empty then
          if tree->data is an operand then
            print (tree->data)
          else
            print (open parenthesis)
            infix (tree->left)
            print (tree->data)
            infix (tree->right)
            print (close parenthesis)
          end
        end
      End infix
      
    • Biểu thức hậu tố (Postfix): Duyệt hậu tự (postfix(tree->left), postfix(tree->right), print(tree->data)).
    • Biểu thức tiền tố (Prefix): Duyệt tiền tự (print(tree->data), prefix(tree->left), prefix(tree->right)).

5. Cây tìm kiếm nhị phân (Binary Search Trees - BST)

  • Định nghĩa ràng buộc khóa: Cây nhị phân mà tại mỗi nút, toàn bộ khóa thuộc cây con bên trái nhỏ hơn khóa của nút gốc ($\text{All} < K$), toàn bộ khóa thuộc cây con bên phải lớn hơn hoặc bằng khóa của nút gốc ($\text{All} \ge K$), và mọi cây con đều là một BST.
  • Tính chất duyệt: Duyệt trung tự (Inorder traversal) trên BST luôn tạo ra một danh sách khóa được sắp xếp tăng dần.
  • Hệ thống giải thuật thao tác:
    • Tìm nút nhỏ nhất (findSmallestBST): Điểm tận cùng bên trái của cây (root->left == NULL).
    • Tìm nút lớn nhất (findLargestBST): Điểm tận cùng bên phải của cây (root->right == NULL).
    • Tìm kiếm đệ quy (searchBST): So sánh target với root->data.key; rẽ trái nếu nhỏ hơn, rẽ phải nếu lớn hơn, trả về nút nếu bằng nhau hoặc NULL nếu cây rỗng.
    • Tìm kiếm lặp (iterativeSearchBST): Dùng vòng lặp while (root != NULL and root->data.key != target) để di chuyển con trỏ xuống các nhánh con tương ứng.

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

  • Cơ sở lý thuyết đồ thị: Ứng dụng mô hình đồ thị có hướng không chu trình để thiết lập quan hệ phân cấp nút - nhánh.
  • Tư duy đệ quy (Recursion): Khai thác cấu trúc tự tương đồng (self-similarity) của cây để xây dựng các giải thuật duyệt và tìm kiếm ngắn gọn, chính xác.
  • Mối quan hệ toán học về độ phức tạp: Chứng minh sự tương quan giữa chiều cao cây $H$ và kích thước dữ liệu $N$, giải thích vì sao cây cân bằng đạt độ phức tạp tìm kiếm $O(\log_2 N)$ trong khi cây suy biến thành danh sách liên kết có chi phí $O(N)$.

Kỹ năng phát triển

  • Kỹ năng thiết kế kỹ thuật (Technical skills): Xây dựng cấu trúc dữ liệu tự trỏ bằng con trỏ trong C/C++, kiểm soát cấp phát bộ nhớ động cho các nút của cây.
  • Kỹ năng phân tích (Analytical skills): Khả năng nhận diện cây hợp lệ/không hợp lệ theo chuẩn BST; phân tích sự cân bằng của cây thông qua tính toán hệ số $B$.
  • Kỹ năng thuật toán (Practical competencies): Chuyển đổi linh hoạt giữa biểu diễn đệ quy và biểu diễn lặp, sử dụng hàng đợi (Queue) để giải quyết bài toán duyệt theo chiều rộng.

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

Phương pháp sư phạm (Pedagogical approach)

Bài giảng áp dụng phương pháp sư phạm cấu trúc tuyến tính logic:

  1. Xác lập định nghĩa toán học và thuật ngữ chuẩn hóa.
  2. Trực quan hóa cấu trúc trừu tượng qua hình vẽ phân mức (Level 0, Level 1, Level 2).
  3. Trình bày cấu trúc dữ liệu lưu trữ vật lý tương ứng.
  4. Trình bày thuật toán bằng mã giả chuẩn có mô tả tiền điều kiện (Pre), hậu điều kiện (Post), tham số truyền (val).

Bài tập và phân tích trường hợp (Case studies)

  • Nhận diện thành phần cấu trúc: Phân tích một cây cụ thể gồm các nút ${a, b, c, d, e, f, g, h, i}$ để xác định nút cha, nút con, nút anh em, nút nội, nút lá và tính toán chiều cao cây ($H = 3$).
  • Kiểm tra tính hợp lệ của cây BST: Cung cấp các ví dụ đối chiếu giữa cây tìm kiếm nhị phân đúng chuẩn (Valid BST) và các trường hợp sai quy tắc (Invalid BST - khi một nút ở nhánh phải nhỏ hơn gốc hoặc nhánh trái lớn hơn gốc).

Thực hành và cài đặt (Practical exercises)

  • Triển khai mã nguồn C/C++ cho các cấu trúc node và binaryTree.
  • Hiện thực hóa hàng đợi bfQueue phục vụ thuật toán duyệt theo chiều rộng.
  • Viết hàm tìm kiếm đệ quy và khử đệ quy (chuyển sang vòng lặp while) trên cây BST.

Phương pháp đánh giá (Assessment methods)

Người học được đánh giá qua:

  • Khả năng tính toán các chỉ số: $H_{min}, H_{max}, N_{min}, N_{max}$, hệ số cân bằng $B$.
  • Khả năng trace (theo dõi từng bước) kết quả duyệt cây qua 4 phương pháp NLR, LNR, LRN và Level-order.
  • Khả năng vẽ lại từng bước quá trình tự cân bằng của cây AVL và B-Tree khi gặp các trường hợp mất cân bằng.
  • Đánh giá mã nguồn chương trình C/C++ và phân tích độ phức tạp Big-O.

Điểm nổi bật và ứng dụng thực tế

Cập nhật và tối ưu hóa so với cấu trúc dữ liệu tuyến tính

Trong các cấu trúc tuyến tính (như mảng hoặc danh sách liên kết), người lập trình phải đánh đổi giữa tốc độ tìm kiếm và tốc độ cập nhật:

  • Mảng đã sắp xếp: Tìm kiếm nhanh ($O(\log N)$ qua Binary Search) nhưng thêm/xóa phần tử chậm ($O(N)$).
  • Danh sách liên kết: Thêm/xóa phần tử nhanh tại vị trí trỏ ($O(1)$) nhưng tìm kiếm tuần tự chậm ($O(N)$).

Cây tìm kiếm nhị phân (BST) dung hòa hai ưu điểm trên: cho phép tìm kiếm nhanh tương đương tìm kiếm nhị phân trên mảng, đồng thời hỗ trợ thao tác chèn và xóa linh hoạt nhờ cấu trúc liên kết con trỏ.

Các ứng dụng thực tế được nêu trong tài liệu

Tài liệu chỉ rõ 4 nhóm ứng dụng tiêu biểu của cấu trúc cây trong khoa học máy tính:

  1. Biểu diễn dữ liệu phân cấp (Hierarchical data): Ứng dụng trong hệ thống tập tin (thư mục và tệp con), sơ đồ tổ chức doanh nghiệp.
  2. Lưu trữ dữ liệu phục vụ tìm kiếm nhanh (Easily searchable storage): Triển khai các cấu trúc chỉ mục dữ liệu thông qua BST và cây tự cân bằng (AVL, B-tree).
  3. Biểu diễn danh sách có thứ tự (Sorted lists of data): Khai thác phép duyệt trung tự (Inorder traversal) trên BST để thu được dãy phần tử có thứ tự mà không cần chạy thuật toán sắp xếp độc lập.
  4. Thuật toán định tuyến mạng (Network routing algorithms): Xây dựng bảng định tuyến và cây khung để tối ưu hóa đường truyền dữ liệu trong hệ thống mạng máy tính.
  5. Phân tích cú pháp biểu thức số học: Cây biểu thức (Expression Tree) đóng vai trò trung tâm trong module xử lý biểu thức của trình biên dịch (Compiler).

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

Phân loại đối tượng học tập

  • Sinh viên đại học: Sinh viên năm thứ hai chuyên ngành Khoa học Máy tính, Kỹ thuật Máy tính, Công nghệ Thông tin, Hệ thống Thông tin đang theo học học phần Cấu trúc dữ liệu và Giải thuật.
  • Học viên cao học/Kỹ sư phần mềm: Đối tượng cần hệ thống hóa lại nền tảng giải thuật, chuẩn bị cho các kỳ đánh giá kỹ thuật chuyên sâu về cấu trúc dữ liệu và giải thuật.

Yêu cầu kiến thức nền tảng (Prerequisites)

Để tiếp thu trọn vẹn kiến thức Chương 7, người học cần có các kiến thức tiên quyết:

  • Kỹ năng lập trình cơ bản với ngôn ngữ C hoặc C++ (cú pháp, kiểu dữ liệu, hàm).
  • Khái niệm con trỏ (pointers), địa chỉ ô nhớ và cơ chế cấp phát động.
  • Cấu trúc dữ liệu tuyến tính cơ bản: Danh sách liên kết đơn, Ngăn xếp (Stack), Hàng đợi (Queue).
  • Khái niệm giải thuật đệ quy (Recursion) và phân tích độ phức tạp thời gian/không gian bằng ký hiệu $O$.

Hướng dẫn sử dụng cho Giảng viên và Tự học

  • Đối với Giảng viên: Tài liệu cung cấp hệ thống chuẩn đầu ra L.1 - L.8 chi tiết, mã giả chuẩn hóa và các hình vẽ minh họa, thích hợp làm đề cương bài giảng lý thuyết và bài tập trên lớp.
  • Đối với người tự học: Tiếp cận theo thứ tự từng slide nội dung; tự viết lại mã giả thành mã C/C++ thực thi; tự giải các bài tập kiểm tra tính hợp lệ của BST và tự dựng cây biểu thức từ các chuỗi toán học.

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

1. Giáo trình này phù hợp nhất với ai?

Tài liệu được thiết kế chuẩn mực cho sinh viên đại học ngành Kỹ thuật và Khoa học Máy tính thuộc Trường Đại học Bách Khoa – ĐHQG-HCM, cũng như người học cần nắm vững lý thuyết và mã giả giải thuật của cấu trúc dữ liệu cây.

2. Cần chuẩn bị những kiến thức nào trước khi học Chương 7?

Người học cần nắm vững kỹ thuật sử dụng con trỏ trong C/C++, cấu trúc dữ liệu danh sách liên kết, hàng đợi (Queue), phương pháp tư duy đệ quy và cách đánh giá độ phức tạp thuật toán bằng Big-O.

3. Khi nào nên cài đặt cây nhị phân bằng mảng thay vì con trỏ liên kết?

Cài đặt cây bằng mảng (Array-based implementation) tối ưu và phù hợp nhất khi áp dụng cho cây nhị phân hoàn chỉnh (complete tree) hoặc gần hoàn chỉnh (nearly complete tree). Khi đó, các phần tử được lấp đầy liên tục trong mảng mà không tạo ra các ô nhớ trống lãng phí, đồng thời dễ dàng tính toán chỉ số nút cha/con qua công thức toán học.

4. Tại sao thuộc tính cân bằng (Balanced feature) lại mang ý nghĩa then chốt trong cấu trúc cây?

Nếu cây nhị phân bị mất cân bằng nghiêm trọng (ví dụ: các nút chỉ lệch về một phía), chiều cao cây $H$ sẽ tiến tới $N$, khiến chi phí tìm kiếm suy biến thành $O(N)$ như danh sách liên kết. Khi cây được duy trì cân bằng (như cây AVL hay B-tree), chiều cao đạt mức tối ưu $H \approx \log_2 N$, đảm bảo hiệu năng tìm kiếm đạt $O(\log N)$.

5. Thứ tự duyệt Inorder trên Cây tìm kiếm nhị phân (BST) có đặc điểm gì đặc biệt?

Phép duyệt Inorder (Left - Node - Right) trên một BST hợp lệ luôn xuất ra các khóa theo thứ tự tăng dần. Đây là phương pháp hiệu quả để trích xuất danh sách đã sắp xếp từ cây tìm kiếm nhị phân mà không cần áp dụng thêm thuật toán sắp xếp bên ngoài.


Kết luận

Chương 7: Cây (Trees) trong giáo trình Cấu trúc dữ liệu và Giải thuật của TS. Nguyễn Hồ Mẫn Răng cung cấp một hệ thống lý thuyết hoàn chỉnh, từ các khái niệm cơ bản về cấu trúc phân cấp, tính chất toán học của cây nhị phân, các giải thuật duyệt cây đa dạng (NLR, LNR, LRN, Level-order), đến các ứng dụng chuyên sâu như Cây biểu thức và Cây tìm kiếm nhị phân.

Lộ trình học tập đề xuất

  1. Nắm chắc định nghĩa hình thức (Node, Branch, Degree, Level, Height).
  2. Nắm vững công thức định lượng cây nhị phân ($H_{min}, H_{max}, N_{min}, N_{max}$, hệ số cân bằng $B$).
  3. Viết và chạy thực nghiệm các giải thuật duyệt đệ quy và duyệt dùng Queue trên C/C++.
  4. Cài đặt các thao tác trên Cây tìm kiếm nhị phân (BST) và nghiên cứu mở rộng sang cơ chế tự cân bằng của Cây AVL và B-Tree theo chuẩn đầu ra L.4 - L.5.