Menu
CoddyTech

Cây nhị phân

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

Cây nhị phân (binary tree) là một cấu trúc phân cấp trong đó mỗi nút có tối đa hai con, gọi là con trái và con phải. Nút trên cùng là gốc, các nút không có con là lá, và số cạnh từ gốc đến lá sâu nhất là chiều cao của cây. Khác với cây tìm kiếm nhị phân, cây nhị phân thông thường không có quy tắc thứ tự nào, nó chỉ là một hình dạng. Nhấn Phát ở trên để xem cây được lấp đầy theo từng tầng, rồi được duyệt trung thứ tự (trái, nút, phải).

Cây nhị phân là nền tảng của nhiều cấu trúc khác: cây tìm kiếm nhị phân, heap, cây biểu thức và nhiều hơn nữa. Các phép duyệt đi qua mọi nút theo một thứ tự xác định: trung thứ tự (in-order), tiền thứ tự (pre-order) và hậu thứ tự (post-order) là ba cách duyệt theo chiều sâu, mỗi cách hữu ích cho một loại việc khác nhau.

Thuật ngữ

Thuật ngữÝ nghĩa
GốcNút trên cùng, không có nút cha
LáNút không có con
Chiều caoĐường đi dài nhất từ gốc đến lá (tính theo cạnh)
Độ sâuKhoảng cách từ một nút đến gốc
Cây hoàn chỉnhMọi tầng đều đầy, có thể trừ tầng cuối, được lấp từ trái sang phải

Ba cách duyệt theo chiều sâu

Cách duyệtThứ tựỨng dụng phổ biến
Trung thứ tựTrái, nút, phảiXuất các giá trị đã sắp xếp của BST
Tiền thứ tựNút, trái, phảiSao chép / tuần tự hóa một cây
Hậu thứ tựTrái, phải, nútXóa / tính giá trị một cây

Ví dụ minh họa

Duyệt trung thứ tự cây được tạo từ [4, 2, 6, 1, 3, 5] (lấp đầy theo từng tầng):

BướcTại nútThao tác
14Đệ quy vào cây con trái của 4 trước khi thăm nút này
22Đệ quy vào cây con trái của 2 trước khi thăm nút này
31Nút lá, không có con trái: thăm 1, kết quả [1]
42Xong bên trái: thăm 2, kết quả [1, 2], rồi đệ quy sang phải
53Nút lá: thăm 3, kết quả [1, 2, 3]
64Xong cây con trái: thăm 4, kết quả [1, 2, 3, 4], rồi đệ quy sang phải
75Con trái của 6, là một lá: thăm 5, kết quả [1, 2, 3, 4, 5]
86Xong bên trái, không có con phải: thăm 6, kết quả [1, 2, 3, 4, 5, 6]

Khi nào nên dùng cây nhị phân

Nên dùng khiTránh dùng khi
Bạn cần mô hình hóa dữ liệu có tính phân cấp tự nhiên (hệ thống tệp, cây biểu thức, DOM)Dữ liệu phẳng và một danh sách hoặc mảng là đủ: cây chỉ tốn thêm chi phí
Bạn muốn các thao tác có thứ tự và có thể giữ cây cân bằng (BST hoặc cây tự cân bằng)Bạn cần tra cứu theo khóa trung bình O(1): bảng băm nhanh hơn mọi loại cây
Bạn cần xử lý dữ liệu có cấu trúc theo trung thứ tự, tiền thứ tự hoặc hậu thứ tựCác nút được chèn theo thứ tự đã sắp xếp vào một BST không cân bằng: cây suy biến thành danh sách O(n)
Truy vấn theo khoảng hoặc duyệt có thứ tự là quan trọng, điều mà bảng băm không làm đượcBộ nhớ eo hẹp: mỗi nút mang hai con trỏ đến nút con cùng với dữ liệu

Code Binary Tree

Một cách cài đặt Binary 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 Tree bằng Python

Python
1from collections import deque2
3
4class Node:5    def __init__(self, value):6        self.value = value7        self.left = None8        self.right = None9
10
11def insert(root, value):12    # Level-order insert: fill the first empty child slot found13    if root is None:14        return Node(value)15    queue = deque([root])16    while queue:17        node = queue.popleft()18        if node.left is None:19            node.left = Node(value)20            return root21        queue.append(node.left)22        if node.right is None:23            node.right = Node(value)24            return root25        queue.append(node.right)26
27
28def inorder(node):29    if node is None:30        return []31    return inorder(node.left) + [node.value] + inorder(node.right)32
33
34root = None35for value in [1, 2, 3, 4, 5, 6, 7]:36    root = insert(root, value)37
38print("Root:   ", root.value)39print("Inorder:", inorder(root))
Chạy code này trong Playground Python

Câu hỏi thường gặp về cây nhị phâ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 chỉ giới hạn mỗi nút có tối đa hai con, không có thứ tự nào. Cây tìm kiếm nhị phân thêm quy tắc: mọi giá trị trong cây con trái nhỏ hơn và mọi giá trị trong cây con phải lớn hơn, và chính điều này giúp tìm kiếm nhanh.

Duyệt trung thứ tự là gì?

Duyệt trung thứ tự thăm cây con trái, rồi đến nút, rồi đến cây con phải, một cách đệ quy. Với cây tìm kiếm nhị phân, cách duyệt này cho ra các giá trị theo thứ tự tăng dần, vì vậy đây là cách duyệt thường được dùng để minh họa nhất.

Cây nhị phân hoàn chỉnh là gì?

Cây nhị phân hoàn chỉnh có mọi tầng đều đầy, có thể trừ tầng cuối, và tầng cuối được lấp từ trái sang phải. Hình dạng này cho phép lưu cây gọn gàng trong một mảng (không cần con trỏ đến nút con), và đó là cách binary heap được cài đặt.

Khi nào nên dùng cây nhị phân thay cho mảng hoặc bảng băm?
Hãy chọn cây khi dữ liệu có tính phân cấp tự nhiên hoặc khi bạn cần các thao tác có thứ tự như truy vấn theo khoảng và duyệt theo thứ tự đã sắp xếp, những điều mà bảng băm không làm được. Nếu bạn chỉ cần tra cứu khóa nhanh mà không cần thứ tự, truy cập trung bình O(1) của bảng băm nhanh hơn cây, còn với dữ liệu phẳng thì mảng đơn giản hơn và thân thiện với bộ nhớ đệm hơn.
Chiều cao và độ sâu của cây nhị phân khác nhau như thế nào?
Độ sâu được đo từ gốc xuống một nút cụ thể, tức là số cạnh trên đường đi từ gốc đến nút đó. Chiều cao được đo từ một nút xuống lá sâu nhất của nó, nên chiều cao của cả cây bằng độ sâu của nút sâu nhất. Một cây chỉ có một nút có chiều cao 0, và nút duy nhất đó cũng có độ sâu 0.
Vì sao cây nhị phân không cân bằng lại chạy chậm như vậy?
Tìm kiếm, chèn và xóa trong cây tìm kiếm nhị phân tốn O(h) với h là chiều cao. Khi các khóa được chèn theo thứ tự đã sắp xếp, cây trở thành một đường thẳng, nên h tăng lên n và mọi thao tác suy biến thành O(n), không hơn gì danh sách liên kết. Các cây tự cân bằng như cây AVL hay cây đỏ đen giữ chiều cao ở mức O(log n) để tránh điều này.
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