Persediaan Temu Duga Pengaturcaraan · Pelajaran

Sisipan dan Carian BST

Laksanakan sisipan dan carian secara rekursif serta lelaran, jejaki laluan melalui pepohon untuk pelbagai kunci dan analisis kerumitan kes terburuk bagi pepohon tidak seimbang.

Pelajaran 1 daripada 413 langkah

Sisipan dan Carian BST ialah pelajaran Persediaan Temu Duga Pengaturcaraan percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Persediaan Temu Duga Pengaturcaraan, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Persediaan Temu Duga Pengaturcaraan merangkumi sejumlah 4 pelajaran.

Takrif Sifat BST

Pepohon Carian Binari memenuhi satu invarian: bagi setiap nod, semua nilai dalam subpepohon kirinya lebih kecil secara ketat daripada nilai nod itu, manakala semua nilai dalam subpepohon kanannya lebih besar secara ketat. Sifat susunan ini dikekalkan pada seluruh subpepohon, bukan hanya pada nod anak terdekat. Sifat ini membolehkan carian, penyisipan dan pemadaman dalam O(log n) pada pepohon seimbang, serta membezakan BST daripada pepohon binari umum.

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

# Valid BST:
#       4
#      / \
#     2   6
#    / \ / \
#   1  3 5  7
# For node 4: left subtree {1,2,3} < 4 < right subtree {5,6,7}
# This holds recursively for EVERY node in the tree.
print('BST property: left < node < right at every level')

Carian BST Rekursif

Carian BST berfungsi seperti carian binari: bandingkan sasaran dengan nilai nod semasa dan lakukan rekursi pada subpepohon yang sesuai. Jika sasaran sama dengan nilai semasa, pulangkan nod itu. Jika sasaran lebih kecil, pergi ke kiri; jika lebih besar, pergi ke kanan. Pulangkan nilai kosong jika mencapai nod kosong. Kerumitan masa ialah O(h) — O(log n) bagi pepohon seimbang dan O(n) bagi pepohon senget.

def search_bst(root, val):
    if not root:
        return None  # not found
    if root.val == val:
        return root  # found
    if val < root.val:
        return search_bst(root.left, val)
    else:
        return search_bst(root.right, val)

root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(7)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)

result = search_bst(root, 2)
print(result.val if result else 'Not found')  # 2
result = search_bst(root, 5)
print(result.val if result else 'Not found')  # Not found

Carian BST Lelaran

Carian lelaran mengelakkan lebihan penggunaan tindanan panggilan dan lebih sesuai untuk kod dalam persekitaran sebenar. Gunakan penuding curr yang bergerak ke bawah pepohon, mengikut arah kiri atau kanan berdasarkan perbandingan. Ini ialah gelung while mudah dengan tiga kes: kosong (tidak ditemui), sepadan (ditemui), atau ubah arah. Carian lelaran juga mengambil masa O(h), tetapi menggunakan ruang O(1) berbanding O(h) untuk versi rekursif.

def search_bst_iterative(root, val):
    curr = root
    while curr:
        if val == curr.val:
            return curr
        elif val < curr.val:
            curr = curr.left
        else:
            curr = curr.right
    return None  # not found

root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(7)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)

node = search_bst_iterative(root, 3)
print(node.val if node else 'Not found')  # 3
print(search_bst_iterative(root, 9))     # None

Penyisipan BST Rekursif

Penyisipan BST mencari kedudukan yang betul dengan mengikuti keputusan kiri/kanan yang sama seperti carian, kemudian memasangkan nod baharu pada kedudukan null pertama yang dicapai. Pendekatan rekursif mengembalikan akar bagi setiap subpepohon, yang mungkin merupakan akar baharu: jika nod semasa ialah kosong, pulangkan TreeNode baharu; jika tidak, kemas kini root.left atau root.right dengan hasil panggilan rekursif. Pola ini kemas dan lazim dalam penyelesaian temu duga.

def insert_bst(root, val):
    if not root:
        return TreeNode(val)  # create new node here
    if val < root.val:
        root.left = insert_bst(root.left, val)
    elif val > root.val:
        root.right = insert_bst(root.right, val)
    # val == root.val: duplicate, do nothing (or handle as needed)
    return root

root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(7)
root = insert_bst(root, 1)
root = insert_bst(root, 5)
# Tree is now: 4, left=2(left=1), right=7(left=5)
print(root.right.left.val)  # 5

Penyisipan BST Lelaran

Penyisipan lelaran menggunakan penuding parent untuk menjejaki nod bukan kosong terakhir sebelum mencapai kedudukan penyisipan. Bergerak ke bawah pepohon seperti dalam carian, sambil menjejaki nod induk dan arah terakhir yang diambil. Apabila mencapai nilai kosong, pasangkan nod baharu pada sisi yang sesuai bagi nod induk. Sentiasa kendalikan kes khas pepohon kosong (akar ialah nilai kosong) secara berasingan.

def insert_bst_iterative(root, val):
    new_node = TreeNode(val)
    if not root:
        return new_node
    curr = root
    while True:
        if val < curr.val:
            if curr.left is None:
                curr.left = new_node
                break
            curr = curr.left
        else:  # val > curr.val
            if curr.right is None:
                curr.right = new_node
                break
            curr = curr.right
    return root

root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(7)
root = insert_bst_iterative(root, 3)
print(root.left.right.val)  # 3

BST Kes Terburuk: Pepohon Senget

Jika anda menyisipkan jujukan tersusun ke dalam BST, anda akan mendapat pepohon senget yang merosot menjadi senarai terpaut. Carian, penyisipan dan pemadaman semuanya menjadi O(n). Sebab itulah BST seimbang seperti pepohon AVL dan pepohon Merah-Hitam diwujudkan. Dalam temu duga, sentiasa nyatakan kes terburuk ini apabila ditanya tentang kerumitan BST — menyebut “O(log n) secara purata, O(n) dalam kes terburuk bagi pepohon tidak seimbang” menunjukkan pemahaman yang mendalam.

# Inserting 1, 2, 3, 4, 5 into a BST:
# 1
#  \
#   2
#    \
#     3
#      \
#       4
#        \
#         5
# This is a right-skewed tree: search is O(n) not O(log n)

root = None
for val in [1, 2, 3, 4, 5]:
    root = insert_bst(root, val)

# Verify the skew
node = root
depth = 0
while node:
    depth += 1
    node = node.right
print(f'Height: {depth}')  # 5 = O(n), not O(log n)

Mencari Nilai Minimum dan Maksimum

Dalam BST, nilai minimum sentiasa berada pada nod paling kiri (terus bergerak ke kiri sehingga mencapai nilai kosong), manakala nilai maksimum berada pada nod paling kanan. Operasi O(h) ini kerap digunakan sebagai rutin bantuan dalam pemadaman BST (untuk mencari pengganti dalam tertib) dan pertanyaan julat. Mengingati fungsi pembantu ini dengan lancar dapat menjimatkan masa dalam temu duga.

def find_min(root):
    while root.left:
        root = root.left
    return root

def find_max(root):
    while root.right:
        root = root.right
    return root

root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(7)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
root.right.right = TreeNode(9)

print(find_min(root).val)  # 1
print(find_max(root).val)  # 9

Pengganti dan Pendahulu dalam Tertib

Pengganti dalam tertib bagi sesuatu nod ialah nod dengan nilai terkecil yang lebih besar daripadanya. Jika nod itu mempunyai subpepohon kanan, penggantinya ialah find_min(node.right). Jika tiada subpepohon kanan, penggantinya ialah leluhur paling rendah yang menjadikan nod tersebut berada dalam subpepohon kiri. Memahami perkara ini amat penting untuk masalah pemadaman BST dan lelaran BST.

def inorder_successor(root, p):
    successor = None
    while root:
        if p.val < root.val:
            successor = root  # possible successor
            root = root.left
        else:
            root = root.right
    return successor

def inorder_predecessor(root, p):
    predecessor = None
    while root:
        if p.val > root.val:
            predecessor = root  # possible predecessor
            root = root.right
        else:
            root = root.left
    return predecessor

root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(6)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
p = root.left  # node with val=2
print(inorder_successor(root, p).val)   # 3
print(inorder_predecessor(root, p).val) # 1

Analisis Kerumitan Carian BST

Prestasi BST bergantung sepenuhnya pada ketinggian pepohon. Bagi BST seimbang dengan n nod, ketinggiannya ialah O(log n), lalu carian, penyisipan dan pemadaman mengambil masa O(log n). Bagi BST senget, ketinggiannya ialah O(n), lalu semua operasi mengambil masa O(n). Python tidak mempunyai BST seimbang terbina dalam (tidak seperti TreeMap Java), jadi anda perlu melaksanakan AVL atau pepohon Merah-Hitam sendiri, menggunakan sortedcontainers.SortedList, atau bergantung pada timbunan untuk kes penggunaan baris gilir keutamaan.

# Python's BST alternatives:
# 1. heapq - min/max heap, O(log n) push/pop
# 2. sortedcontainers.SortedList (third-party, often allowed)
# 3. Manual AVL or Red-Black (rarely required in interviews)

# When interviews say 'use a BST':
# - LeetCode: implement TreeNode-based solution
# - Real interview: mention sortedcontainers or Java TreeMap equivalent
# - O(log n) operations matter when you need ordered access

# For pure insert/lookup without ordering: use dict (O(1) average)
print('Use heap for priority, dict for lookup, BST for ordered range')

Penyisipan ke dalam BST: Kes Khas

Sentiasa pastikan penyisipan anda mengendalikan: pepohon kosong (pulangkan nod baharu sebagai akar), nilai pendua (tentukan sama ada untuk mengabaikannya, menyisipkannya ke kiri atau menyisipkannya ke kanan — dan kekalkan keputusan itu secara konsisten), serta nilai yang sangat besar atau kecil. Dalam temu duga, nyatakan andaian tentang pendua sebelum menulis kod. Konvensyen yang paling lazim dalam masalah LeetCode ialah semua nilai adalah berbeza kecuali dinyatakan sebaliknya.

def insert_bst_no_duplicates(root, val):
    if not root:
        return TreeNode(val)
    if val < root.val:
        root.left = insert_bst_no_duplicates(root.left, val)
    elif val > root.val:
        root.right = insert_bst_no_duplicates(root.right, val)
    # else: val == root.val -> duplicate, skip
    return root

# Test all edge cases:
root = None
root = insert_bst_no_duplicates(root, 5)  # empty tree
root = insert_bst_no_duplicates(root, 5)  # duplicate
root = insert_bst_no_duplicates(root, 3)
root = insert_bst_no_duplicates(root, 7)
print(root.val, root.left.val, root.right.val)  # 5 3 7

BST daripada Tatasusunan Tersusun

Membina BST seimbang dari segi ketinggian daripada tatasusunan tersusun (LeetCode #108) menggunakan kaedah bahagi dan takluk: elemen tengah menjadi akar, separuh kiri menjadi subpepohon kiri, dan separuh kanan menjadi subpepohon kanan. Ini menjamin pepohon seimbang dengan ketinggian O(log n). Kerumitan masa ialah O(n) kerana setiap elemen diproses sekali.

def sorted_array_to_bst(nums):
    if not nums:
        return None
    mid = len(nums) // 2
    root = TreeNode(nums[mid])
    root.left = sorted_array_to_bst(nums[:mid])
    root.right = sorted_array_to_bst(nums[mid+1:])
    return root

nums = [-10, -3, 0, 5, 9]
root = sorted_array_to_bst(nums)
print(root.val)        # 0 (middle element)
print(root.left.val)   # -3
print(root.right.val)  # 9

Semakan Pantas

Uji pemahaman anda tentang konsep Struktur Data & Algoritma — Persediaan Temu Duga Pengekodan daripada pelajaran ini.

Ulang Kaji Pelajaran

Dalam pelajaran ini, anda telah mempelajari: sifat BST (subpepohon kiri lebih kecil secara ketat, subpepohon kanan lebih besar secara ketat), carian dan penyisipan secara rekursif dan lelaran dalam masa O(h), serta pepohon senget dalam kes terburuk yang ketinggiannya sama dengan n. Seterusnya, kita akan membincangkan pemadaman BST dan tiga kesnya.

Percuma untuk bermula

Pelajari Persediaan Temu Duga Pengaturcaraan dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
90
Pelajaran
360

Soalan Lazim

Adakah pelajaran “Sisipan dan Carian BST” percuma?

Ya — teks penuh “Sisipan dan Carian BST” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Persediaan Temu Duga Pengaturcaraan, tingkat taraf kepada CoddyKit PRO. Kursus Persediaan Temu Duga Pengaturcaraan merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Sisipan dan Carian BST”?

Laksanakan sisipan dan carian secara rekursif serta lelaran, jejaki laluan melalui pepohon untuk pelbagai kunci dan analisis kerumitan kes terburuk bagi pepohon tidak seimbang. Anda berlatih Persediaan Temu Duga Pengaturcaraan menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Persediaan Temu Duga Pengaturcaraan?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Persediaan Temu Duga Pengaturcaraan di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.

Berapa lamakah pelajaran “Sisipan dan Carian BST” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Persediaan Temu Duga Pengaturcaraan ini?

Ya. Setiap pelajaran Persediaan Temu Duga Pengaturcaraan menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Sisipan dan Carian BST
  2. Pemadaman BST: Tiga Kes
  3. Mengesahkan BST dan Sifat Dalam Susunan
  4. Unsur Ke-K Terkecil, Jumlah Julat dan BST kepada Tatasusunan Tersusun
← Kembali ke Persediaan Temu Duga Pengaturcaraan