Ikkilik qidiruv daraxti
Ikkilik qidiruv daraxti (Binary Search Tree — BST) — sonlarning saralangan ro'yxatini tezkor usulda saqlash va boshqarish imkonini beruvchi ma'lumotlar tuzilmasidir:
O(log n) vaqt ichida qidirib topish mumkin.Ikkilik qidiruv daraxtini oddiy ikkilik daraxtdan ajratib turuvchi asosiy xossalar:

BST va BST bo'lmagan daraxt taqqoslanishi
Yuqoridagi rasmning o'ng tomonidagi daraxt BST emas, chunki "3" tugunining o'ng quyi daraxtida undan kichik bo'lgan "2" tuguni joylashib qolgan.
Qidirish algoritmi BST xossasiga tayanadi: agar qidirilayotgan qiymat ildizdan kichik bo'lsa, u aniq o'ng quyi daraxtda bo'lishi mumkin emas — biz faqat chap quyi daraxtni qidirishimiz kerak. Agar u ildizdan katta bo'lsa, faqat o'ng quyi daraxtni qidiramiz.
If root == NULL
return NULL;
If number == root.data
return root.data;
If number < root.data
return search(root.left)
If number > root.data
return search(root.right)
Qidiruv jarayonini bosqichma-bosqich ko'rib chiqamiz (masalan, 4 qiymatini qidiramiz):
4 < 8 bo'lgani sababli, chap quyi daraxtga o'tiladi:
4 topilmadi, 8 ning chap quyi daraxtiga o'tish
4 > 3 bo'lgani uchun o'ng quyi daraxtga o'tiladi:
4 topilmadi, 3 ning o'ng quyi daraxtiga o'tish
4 < 6 bo'lgani sababli, chap quyi daraxtga o'tiladi:
4 topilmadi, 6 ning chap quyi daraxtiga o'tish

4 qiymati muvaffaqiyatli topildi

Qiymat rekursiya bo'yicha yuqoriga uzatiladi
Agar qiymat mavjud bo'lmasa, oxir-oqibat barg tugunning bo'sh bolasiga (NULL) yetib boriladi va NULL qaytariladi.
Qiymatni to'g'ri o'ringa qo'shish qidirish amaliga juda o'xshaydi, chunki yangi tugun qo'shilgandan so'ng ham daraxt BST qoidalariga mos qolishi kerak.
If node == NULL
return createNode(data)
if (data < node.data)
node.left = insert(node.left, data);
else if (data > node.data)
node.right = insert(node.right, data);
return node;
Qo'shish jarayonini amalda ko'ramiz (masalan, 4 sonini qo'shamiz):
4 < 8, shuning uchun 8 ning chap bolasiga o'tamiz:
4 < 8, chap bolaga o'tish
4 > 3, shuning uchun 3 ning o'ng bolasiga o'tamiz:
4 > 3, o'ng bolaga o'tish
4 < 6, shuning uchun 6 ning chap bolasiga o'tamiz:
4 < 6, chap bolaga o'tish

4 ni 6 ning chap bolasi sifatida qo'shish
return node qilinadi:
Ildiz tugunlarni saqlagan holda yuqoriga qaytish
Ikkilik qidiruv daraxtidan tugunni o'chirishning 3 ta holati mavjud:
Agar tugunning bolalari bo'lmasa, uni shunchaki daraxtdan olib tashlash kifoya:

Barg tugunni (4) tanlash

Barg tugunni o'chirish
Ushbu holatda:

6 tugunini tanlash (uning faqat bitta bolasi bor: 7)

Bola qiymatini o'rniga ko'chirish

Yakuniy daraxt holati
Ushbu holatda:

Ikkita bolaga ega bo'lgan 3 tugunini o'chirish

Inorder vorisi (4) ning qiymatini 3 ning o'rniga ko'chirish

Inorder vorisini asl o'rnidan o'chirish
// Go tilida Ikkilik qidiruv daraxti (Binary Search Tree - BST) amallari
package main
import "fmt"
type Node struct {
key int
left *Node
right *Node
}
func newNode(key int) *Node {
return &Node{key: key}
}
// Inorder aylanib chiqish (saralangan tartibda)
func inorder(root *Node) {
if root != nil {
inorder(root.left)
fmt.Printf("%d-> ", root.key)
inorder(root.right)
}
}
// Tugun qo'shish (Insert)
func insert(node *Node, key int) *Node {
// Agar daraxt bo'sh bo'lsa, yangi tugun qaytariladi
if node == nil {
return newNode(key)
}
// Qiymatiga qarab chap yoki o'ng quyi daraxtga yo'naltiriladi
if key < node.key {
node.left = insert(node.left, key)
} else if key > node.key {
node.right = insert(node.right, key)
}
return node
}
// Inorder vorisini (o'ng quyi daraxtdagi eng kichik elementni) topish
func minValueNode(node *Node) *Node {
current := node
for current != nil && current.left != nil {
current = current.left
}
return current
}
// Tugunni o'chirish (Delete)
func deleteNode(root *Node, key int) *Node {
if root == nil {
return root
}
if key < root.key {
root.left = deleteNode(root.left, key)
} else if key > root.key {
root.right = deleteNode(root.right, key)
} else {
// 1 yoki 0 ta bolaga ega bo'lgan holat
if root.left == nil {
return root.right
} else if root.right == nil {
return root.left
}
// 2 ta bolaga ega bo'lgan holat:
// O'ng quyi daraxtdagi eng kichik tugun (inorder successor) topiladi
temp := minValueNode(root.right)
root.key = temp.key
// Inorder successor o'chirib tashlanadi
root.right = deleteNode(root.right, temp.key)
}
return root
}
func main() {
var root *Node
root = insert(root, 8)
root = insert(root, 3)
root = insert(root, 1)
root = insert(root, 6)
root = insert(root, 7)
root = insert(root, 10)
root = insert(root, 14)
root = insert(root, 4)
fmt.Print("Inorder traversal: ")
inorder(root)
fmt.Println("\n\n10 o'chirilmoqda (Delete 10)")
root = deleteNode(root, 10)
fmt.Print("Inorder traversal: ")
inorder(root)
fmt.Println()
}| Amal (Operation) | Eng yaxshi holat (Best Case) | O'rtacha holat (Average Case) | Eng yomon holat (Worst Case) |
|---|---|---|---|
| Qidirish (Search) | O(log n) | O(log n) | O(n) |
| Qo'shish (Insertion) | O(log n) | O(log n) | O(n) |
| O'chirish (Deletion) | O(log n) | O(log n) | O(n) |
Bu yerda n — daraxtdagi tugunlarning umumiy soni. Eng yomon holat daraxt bitta chiziqqa cho'zilib (skewed tree) ketganda yuzaga keladi.
Barcha amallar uchun xotira murakkabligi O(n) ni tashkil etadi.