Menu
CoddyTech

Cây tìm kiếm nhị phân (BST)

Cập nhật lần cuối

Cây tìm kiếm nhị phân (binary search tree) giữ các giá trị theo thứ tự: với mỗi nút, mọi giá trị trong cây con trái đều nhỏ hơn và mọi giá trị trong cây con phải đều lớn hơn. Để chèn hoặc tìm một giá trị, bạn bắt đầu từ gốc rồi liên tục đi sang trái hoặc phải tùy kết quả so sánh, nên mỗi bước loại đi một nửa phạm vi tìm kiếm. Nhấn Phát ở trên để xem các giá trị được đặt vào nhờ so sánh và một lượt tìm kiếm đi dần xuống cây.

Trên cây cân bằng, các thao tác này chạy trong thời gian O(log n). Điểm yếu là: chèn dữ liệu đã sắp xếp sẽ khiến cây suy biến thành danh sách liên kết với các thao tác O(n), và đó chính là lý do các biến thể tự cân bằng như cây AVL và cây đỏ đen ra đời.

Độ phức tạp thời gian và không gian

Thao tácCân bằngXấu nhất (cây lệch)
Tìm kiếmO(log n)O(n)
ChènO(log n)O(n)
XóaO(log n)O(n)
Không gianO(n)O(n)

Từng bước thực hiện (chèn)

BướcĐiều gì xảy ra
1Nếu cây rỗng, giá trị mới trở thành gốc.
2Nếu không, bắt đầu từ gốc.
3Nếu giá trị nhỏ hơn, đi sang con trái; nếu lớn hơn, đi sang phải.
4Lặp lại cho đến khi gặp một vị trí trống.
5Gắn giá trị mới vào đó như một nút lá.

Ví dụ minh họa

Chèn lần lượt từng giá trị của [5, 3, 8, 1, 4] vào một cây rỗng:

ChènĐường điThao tác
5-Cây rỗng, nên 5 trở thành gốc.
353 < 5, đi sang trái; vị trí còn trống, gắn 3 làm con trái của 5.
858 > 5, đi sang phải; vị trí còn trống, gắn 8 làm con phải của 5.
15 -> 31 < 5 đi sang trái, rồi 1 < 3 đi sang trái; gắn 1 làm con trái của 3.
45 -> 34 < 5 đi sang trái, rồi 4 > 3 đi sang phải; gắn 4 làm con phải của 3.

Khi nào nên dùng cây tìm kiếm nhị phân

Nên dùng khiTránh dùng khi
Bạn cần cả thứ tự sắp xếp lẫn tra cứu nhanh, và dữ liệu được chèn theo thứ tự ngẫu nhiên.Dữ liệu đến theo thứ tự đã sắp xếp: một BST không cân bằng suy biến thành O(n) mỗi thao tác.
Bạn muốn phép duyệt trung thứ tự tự động cho ra các giá trị đã sắp xếp.Bạn chỉ cần kiểm tra phần tử có tồn tại hay không, không cần thứ tự: bảng băm cho tra cứu trung bình O(1).
Bạn cần truy vấn theo khoảng hoặc tìm phần tử liền sau/liền trước của một khóa.Bạn cần bảo đảm cận O(log n): hãy dùng cây AVL hoặc cây đỏ đen tự cân bằng.
Tập dữ liệu thay đổi thường xuyên và việc cập nhật một mảng tĩnh đã sắp xếp sẽ tốn kém.Tập dữ liệu cố định và chỉ đọc: mảng đã sắp xếp cùng tìm kiếm nhị phân đơn giản hơn và thân thiện với bộ nhớ đệm.

Code Binary Search Tree

Một cách cài đặt Binary Search Tree gọn gàng, chạy được ngay bằng Python, JavaScript, Java, C++, C. Chọn một ngôn ngữ, sao chép code hoặc mở sẵn trong Coddy Playground.

Code Binary Search Tree bằng Python

Python
1class Node:2    def __init__(self, key):3        self.key = key4        self.left = None5        self.right = None6
7
8def insert(node, key):9    if node is None:10        return Node(key)11    if key < node.key:12        node.left = insert(node.left, key)13    elif key > node.key:14        node.right = insert(node.right, key)15    return node  # duplicates are ignored16
17
18def search(node, key):19    if node is None:20        return False21    if key == node.key:22        return True23    if key < node.key:24        return search(node.left, key)25    return search(node.right, key)26
27
28def inorder(node):29    if node is None:30        return []31    return inorder(node.left) + [node.key] + inorder(node.right)32
33
34root = None35for key in [8, 3, 10, 1, 6, 14, 4, 7]:36    root = insert(root, key)37
38print("Inorder (sorted):", inorder(root))39print("search(6): ", search(root, 6))40print("search(5): ", search(root, 5))
Chạy code này trong Playground Python

Câu hỏi thường gặp về cây tìm kiếm nhị phân

Độ phức tạp thời gian của cây tìm kiếm nhị phân là bao nhiêu?
Tìm kiếm, chèn và xóa đều là O(log n) trên cây cân bằng, vì mỗi lần so sánh loại bỏ một nửa số nút còn lại. Trong trường hợp xấu nhất, khi cây bị lệch thành một chuỗi do chèn dữ liệu đã sắp xếp, các thao tác này suy biến thành O(n).
Cây nhị phân và cây tìm kiếm nhị phân khác nhau như thế nào?

Cây nhị phân là bất kỳ cây nào mà mỗi nút có tối đa hai con, không có quy tắc thứ tự nào. Cây tìm kiếm nhị phân thêm bất biến: giá trị ở cây con trái nhỏ hơn và giá trị ở cây con phải lớn hơn nút đó, và chính điều này giúp tìm kiếm nhanh.

Vì sao cây tìm kiếm nhị phân có thể trở nên chậm?
Nếu các giá trị được chèn theo thứ tự tăng dần (hoặc giảm dần), mọi nút mới đều đi về cùng một phía, tạo ra một cây cao và lệch, hoạt động giống danh sách liên kết với O(n) mỗi thao tác. Các cây tự cân bằng (AVL, đỏ đen) xoay các nút để tránh điều này.
Cây tìm kiếm nhị phân và bảng băm khác nhau như thế nào?
Bảng băm cho tra cứu trung bình O(1) nhưng không lưu khóa theo thứ tự nào, nên không trả lời được truy vấn theo khoảng hay tìm phần tử liền sau. Cây tìm kiếm nhị phân chậm hơn một chút với O(log n) nhưng giữ khóa theo thứ tự, cho phép duyệt theo thứ tự đã sắp xếp và tìm giá trị gần nhất. Chọn BST khi thứ tự quan trọng, chọn bảng băm khi bạn chỉ cần kiểm tra sự tồn tại.
Khi nào nên dùng cây tự cân bằng thay cho BST thông thường?
Dùng cây tự cân bằng (AVL, đỏ đen) bất cứ khi nào bạn không kiểm soát được thứ tự chèn và cần bảo đảm hiệu năng O(log n). BST thông thường phù hợp để học, cho tập dữ liệu nhỏ, hoặc khi khóa đến theo thứ tự ngẫu nhiên, nhưng không có gì bảo vệ bạn khỏi trường hợp xấu nhất khi cây bị lệch.
Duyệt trung thứ tự một BST có trả về các giá trị đã sắp xếp không?

Có. Duyệt cây con trái, rồi đến nút, rồi đến cây con phải sẽ cho ra các khóa theo thứ tự tăng dần, đây là hệ quả trực tiếp của bất biến BST. Một sai lầm phổ biến là mong đợi điều tương tự từ một cây nhị phân thông thường: không có quy tắc thứ tự, duyệt trung thứ tự không tạo ra dãy có ý nghĩa nào.

Hình minh họa các ngôn ngữ lập trình của Coddy

Thành thạo thuật toán cùng Coddy

Bắt đầu