Tìm Hiểu Về Cấu Trúc Dữ Liệu Trie

3 min read

Cấu trúc dữ liệu Trie là một cấu trúc dữ liệu cây được sử dụng rộng rãi trong các bài toán liên quan đến xử lý chuỗi. Trie đặc biệt hữu ích trong việc lưu trữ và tìm kiếm từ điển, tự động hoàn thành (autocomplete), và các ứng dụng liên quan đến tiền tố (prefix).

Khái Niệm Cơ Bản

Trie là một cây có thứ tự, trong đó mỗi nút đại diện cho một ký tự của một chuỗi. Các nút con của một nút được sắp xếp theo thứ tự từ điển. Một nút có thể có nhiều nút con, mỗi nút con tương ứng với một ký tự khác nhau.

  • Gốc (Root): Nút gốc của Trie là một nút rỗng, không chứa ký tự.
  • Cạnh (Edge): Mỗi cạnh nối giữa hai nút đại diện cho một ký tự.
  • Nút lá (Leaf Node): Nút lá đại diện cho kết thúc của một chuỗi.

Đặc Điểm Của Trie

  • Tiền Tố Chung: Trie cho phép chia sẻ tiền tố chung giữa các chuỗi, giúp tiết kiệm bộ nhớ.
  • Tìm Kiếm Hiệu Quả: Thời gian tìm kiếm một chuỗi trong Trie là O(m), với m là độ dài của chuỗi.
  • Chèn và Xóa: Thời gian chèn và xóa một chuỗi cũng là O(m).

Ứng Dụng Của Trie

  • Từ Điển: Trie được sử dụng để lưu trữ từ điển và hỗ trợ tìm kiếm từ nhanh chóng.
  • Tự Động Hoàn Thành (Autocomplete): Trie giúp đề xuất các từ có tiền tố giống với từ đang được nhập.
  • Kiểm Tra Chính Tả: Trie có thể được sử dụng để kiểm tra xem một từ có tồn tại trong từ điển hay không.
  • Đếm Số Lần Xuất Hiện: Trie có thể được sử dụng để đếm số lần xuất hiện của một chuỗi trong một tập hợp.

Triển Khai Trie

Dưới đây là một ví dụ về Trie trong Python:

Đếm Số Lượng Từ Có Chung Tiền Tố

class TrieNode:
    def __init__(self):
        self.children = {}  # Lưu trữ các nút con
        self.count = 0  # Đếm số từ đi qua nút này

class Trie:
    def __init__(self):
        self.root = TrieNode()  # Khởi tạo nút gốc

    def insert(self, word):
        node = self.root
        for char in word:
            if char not in node.children:
                node.children[char] = TrieNode()  # Tạo nút con nếu ký tự chưa tồn tại
            node = node.children[char]
            node.count += 1  # Tăng biến đếm khi đi qua nút

    def count_words_with_prefix(self, prefix):
        node = self.root
        for char in prefix:
            if char not in node.children:
                return 0  # Tiền tố không tồn tại
            node = node.children[char]
        return node.count  # Trả về số lượng từ có chung tiền tố

# Ví dụ sử dụng
trie = Trie()
words = ["apple", "app", "apricot", "banana", "appetizer"]
for word in words:
    trie.insert(word)

print(trie.count_words_with_prefix("app"))  # Output: 3
print(trie.count_words_with_prefix("ap"))   # Output: 4
print(trie.count_words_with_prefix("bana")) # Output: 1
print(trie.count_words_with_prefix("xyz"))  # Output: 0

Giải Thích

  • Cấu Trúc Trie Sau Khi Chèn:
    • Từ “apple”, “app”, “apricot”, “banana”, “appetizer” được chèn vào Trie.
    • Cấu trúc Trie:
  • count_words_with_prefix("app"):
    • Tiền tố “app” xuất hiện trong 3 từ: “apple”, “app”, “appetizer”.
    • Output: 3.
  • count_words_with_prefix("ap"):
    • Tiền tố “ap” xuất hiện trong 4 từ: “apple”, “app”, “apricot”, “appetizer”.
    • Output: 4.
  • count_words_with_prefix("bana"):
    • Tiền tố “bana” xuất hiện trong 1 từ: “banana”.
    • Output: 1.
  • count_words_with_prefix("xyz"):
    • Tiền tố “xyz” không tồn tại trong Trie.
    • Output: 0.

Ưu Điểm và Nhược Điểm

Ưu Điểm:

  • Tìm kiếm, chèn và xóa nhanh chóng.
  • Hiệu quả trong việc xử lý các bài toán liên quan đến tiền tố.

Nhược Điểm:

  • Tốn bộ nhớ do mỗi nút có thể có nhiều con.
  • Không phù hợp với các bài toán có bộ dữ liệu lớn và không có nhiều tiền tố chung.

Kết Luận

Trie là một cấu trúc dữ liệu mạnh mẽ và linh hoạt, đặc biệt phù hợp cho các bài toán liên quan đến chuỗi và tiền tố. Việc hiểu và biết cách triển khai Trie sẽ giúp bạn giải quyết nhiều vấn đề trong lập trình một cách hiệu quả.

Tham khảo: https://www.geeksforgeeks.org/introduction-to-trie-data-structure-and-algorithm-tutorials

Avatar photo

Leave a Reply

Your email address will not be published. Required fields are marked *