Trong quá trình giảng dạy, Code Dream nhận thấy rằng khi học đến các bài toán xử lý chuỗi, nhiều học viên thường gặp khó khăn nếu chỉ sử dụng các phương pháp thông thường. Chính vì vậy, Trie trở thành một cấu trúc dữ liệu “chìa khóa” giúp giải quyết những bài toán này một cách trực quan và hiệu quả hơn. Vậy Trie là gì, có cấu trúc ra sao và hoạt động như thế nào? Cùng tìm hiểu ngay trong bài viết dưới đây nhé!
Trie là gì?
Trie (còn gọi là Prefix Tree) là một cấu trúc dữ liệu dạng cây được thiết kế chuyên biệt để lưu trữ và tìm kiếm các chuỗi ký tự, đặc biệt hiệu quả với các bài toán liên quan đến tiền tố (prefix).
Khác với mảng hay danh sách, Trie lưu trữ từng ký tự của chuỗi vào các node theo từng cấp. Mỗi đường đi từ node gốc đến một node bất kỳ sẽ biểu diễn một tiền tố hoặc một từ hoàn chỉnh.

Đặc điểm nổi bật của Trie:
- Tìm kiếm chuỗi nhanh với độ phức tạp O(L) (L là độ dài chuỗi)
- Dễ dàng kiểm tra tiền tố
- Phù hợp cho từ điển, autocomplete, spell checking
Ví dụ, khi lưu các từ: cat, car, dog, các từ có chung tiền tố “ca” sẽ chia sẻ chung một nhánh trong Trie.
Cấu trúc của Trie
Một Trie thường bao gồm các thành phần sau:
- Node gốc (root): Không chứa ký tự, là điểm bắt đầu của Trie.
- Các node con: Mỗi node đại diện cho một ký tự trong bảng chữ cái (a–z, 0–9,…).
- Cờ kết thúc từ (isEndOfWord): Dùng để đánh dấu node đó là kết thúc của một từ hoàn chỉnh.
Ví dụ: Lưu các từ: to, tea, ten
root
|
t
|
e
/ \
a n
Trong đó: Node o và node a, n sẽ được đánh dấu là kết thúc từ.
Các cách cài đặt Trie phổ biến
Trong thực tế, Trie có thể được cài đặt theo hai cách chính:
1. Cài đặt Trie bằng mảng (Trie tĩnh)
Ý tưởng
Mỗi node của Trie được biểu diễn bằng một chỉ số trong mảng.
Mỗi node có:
- Một mảng next[node][26] lưu chỉ số node con
- Một mảng isEnd[node] đánh dấu kết thúc từ
Toàn bộ Trie dùng chung một mảng lớn.
Ví dụ cài đặt Trie bằng mảng (C++)
const int MAX_NODE = 100000;
int nextNode[MAX_NODE][26];
bool isEnd[MAX_NODE];
int nodeCount = 0; // số node đã dùng
void init() {
nodeCount = 1; // node 0 là root
memset(nextNode, 0, sizeof(nextNode));
memset(isEnd, false, sizeof(isEnd));
}
void insert(string s) {
int cur = 0; // bắt đầu từ root
for (char c : s) {
int idx = c - 'a';
if (nextNode[cur][idx] == 0) {
nextNode[cur][idx] = nodeCount++;
}
cur = nextNode[cur][idx];
}
isEnd[cur] = true;
}
Ưu điểm : Tốc độ nhanh, dễ kiểm soát trong các bài thi
Nhược điểm:
- Phải đoán trước MAX_NODE
- Tốn bộ nhớ nếu Trie nhỏ
- Khó xóa node
2. Cài đặt Trie bằng con trỏ (Trie động)
Ý tưởng
Mỗi node là một struct/class:
- Chứa mảng con trỏ đến các node con
- Chỉ được tạo khi cần
- Dễ quản lý và mở rộng
Ví dụ cài đặt Trie bằng con trỏ (C++)
struct TrieNode {
TrieNode* child[26];
bool isEnd;
TrieNode() {
isEnd = false;
for (int i = 0; i < 26; i++)
child[i] = nullptr;
}
};
TrieNode* root = new TrieNode();
Ưu điểm:
- Bộ nhớ cấp phát linh hoạt
- Dễ tạo nhiều Trie
- Có thể xóa node
Nhược điểm: Tốc độ chậm hơn Trie mảng một chút (do con trỏ)
Câu hỏi thường gặp về Trie
Trong quá trình dạy học, Code Dream nhận thấy học viên không chỉ “vướng” ở lý thuyết mà còn phát sinh rất nhiều câu hỏi thú vị trong quá trình làm bài. Cùng điểm qua một số câu hỏi phổ biến dưới đây nhé!
1. Nên cài đặt Trie theo cách nào?
Nên ưu tiên cài đặt Trie bằng con trỏ vì:
- Không cần ước lượng trước dung lượng bộ nhớ: Với Trie mảng, bạn phải khai báo số lượng node tối đa ngay từ đầu. Nếu ước lượng thiếu sẽ gây lỗi, còn nếu khai báo dư sẽ lãng phí bộ nhớ. Trie con trỏ chỉ tạo node khi cần, giúp sử dụng bộ nhớ linh hoạt hơn.
- Dễ dàng tạo nhiều Trie độc lập: Mỗi Trie chỉ cần một node gốc (root). Khi cần thêm một Trie mới, bạn chỉ việc tạo thêm một root mới mà không ảnh hưởng đến Trie cũ.
- Có thể xóa node không còn sử dụng: Trie con trỏ cho phép giải phóng các node không cần thiết (ví dụ khi xóa từ), điều mà Trie mảng rất khó hoặc gần như không làm được.
2. Trie có ưu điểm gì so với mảng hay map?
Trie cho phép tìm kiếm và kiểm tra tiền tố nhanh hơn, không phụ thuộc vào số lượng từ mà phụ thuộc vào độ dài chuỗi.
3. Nhược điểm của Trie là gì?
Trie tốn bộ nhớ, đặc biệt khi bảng ký tự lớn hoặc số lượng từ nhiều.
4. Khi nào nên dùng Trie?
Không phải bài toán nào liên quan đến chuỗi cũng cần dùng Trie—quan trọng là biết chọn đúng thời điểm để phát huy tối đa sức mạnh của cấu trúc này. Vậy khi nào Trie thực sự là lựa chọn tối ưu? Khi:
- Từ điển
- Tìm kiếm gợi ý (autocomplete)
- Kiểm tra chính tả
- Lọc từ cấm, từ khóa
5. Trie có dùng được trong phỏng vấn không?
Có. Trie là cấu trúc dữ liệu thường xuyên xuất hiện trong các bài toán thuật toán và phỏng vấn lập trình.
Học lập trình, tư duy thuật toán chất lượng tại Code Dream
Hiểu Trie không đơn thuần là ghi nhớ cú pháp hay học thuộc cách cài đặt. Điều quan trọng hơn là nắm được cách tổ chức dữ liệu sao cho tối ưu và biết lựa chọn đúng cấu trúc trong từng bài toán cụ thể. Đây cũng chính là định hướng giảng dạy cốt lõi tại Code Dream: học để hiểu bản chất, không học máy móc.
Tại Code Dream, các cấu trúc dữ liệu như Trie được triển khai theo phương pháp dễ tiếp cận nhưng vẫn đảm bảo chiều sâu:
- Đi từ bản chất vấn đề (vì sao cần Trie) → minh họa trực quan (cây, ví dụ thực tế) → hiện thực bằng code, giúp học viên hiểu rõ từng bước thay vì chỉ sao chép.
- Luôn gắn kiến thức với các bài toán thực tế như tìm kiếm từ khóa, autocomplete, xử lý từ điển, cũng như các dạng bài thường gặp trong phỏng vấn.
- Xây dựng lộ trình học rõ ràng, từ nền tảng cơ bản đến nâng cao, giúp người học không bị “ngợp” mà vẫn tiến bộ vững chắc qua từng giai đoạn.
- Đặc biệt chú trọng rèn luyện tư duy lựa chọn cấu trúc dữ liệu, để học viên biết khi nào nên dùng Trie, khi nào nên dùng giải pháp khác tối ưu hơn.

Trên đây là những kiến thức chi tiết giúp bạn hiểu rõ Trie là gì, cấu trúc của Trie cũng như cách cài đặt. Việc nắm vững Trie không chỉ giúp bạn xử lý hiệu quả các bài toán liên quan đến chuỗi mà còn nâng cao tư duy thuật toán – yếu tố quan trọng đối với bất kỳ lập trình viên nào.
Nếu bạn quan tâm đến khóa học lập trình thuật toán bài bản, được hướng dẫn từ cơ bản đến nâng cao và áp dụng thực tế, đừng ngần ngại tìm hiểu ngay. Đăng ký học ngay tại Code Dream để làm chủ Trie trong lập trình bạn nhé!






