Binar Qidiruv Daraxtlari (BQD) asoslarini o'rganing va ularni JavaScript'da samarali amalga oshirishni bilib oling. Ushbu qo'llanma BQD tuzilishi, amallari va butun dunyodagi dasturchilar uchun amaliy misollarni o'z ichiga oladi.
Binar Qidiruv Daraxtlari: JavaScript'da To'liq Amalga Oshirish Qo'llanmasi
Binar Qidiruv Daraxtlari (BQD) kompyuter fanlarida asosiy ma'lumotlar tuzilmasi bo'lib, ma'lumotlarni samarali qidirish, saralash va olish uchun keng qo'llaniladi. Ularning ierarxik tuzilishi ko'plab amallarda logarifmik vaqt murakkabligini ta'minlaydi, bu ularni katta hajmdagi ma'lumotlar to'plamini boshqarish uchun kuchli vositaga aylantiradi. Ushbu qo'llanma BQD haqida to'liq ma'lumot beradi va ularning JavaScript'da amalga oshirilishini namoyish etadi, bu esa butun dunyodagi dasturchilarga mo'ljallangan.
Binar Qidiruv Daraxtlarini Tushunish
Binar Qidiruv Daraxti Nima?
Binar Qidiruv Daraxti - bu daraxtga asoslangan ma'lumotlar tuzilmasi bo'lib, unda har bir tugun ko'pi bilan ikkita bolaga ega bo'ladi, ular chap bola va o'ng bola deb ataladi. BQD'ning asosiy xususiyati shundaki, har qanday berilgan tugun uchun:
- Chap quyi daraxtdagi barcha tugunlarning kalitlari tugun kalitidan kichik.
- O'ng quyi daraxtdagi barcha tugunlarning kalitlari tugun kalitidan katta.
Bu xususiyat BQD'dagi elementlarning har doim tartiblangan bo'lishini ta'minlaydi, bu esa samarali qidirish va olish imkonini beradi.
Asosiy Tushunchalar
- Tugun (Node): Daraxtdagi asosiy birlik bo'lib, kalit (ma'lumot) va chap va o'ng bolalariga ishoralarni o'z ichiga oladi.
- Ildiz (Root): Daraxtdagi eng yuqori tugun.
- Barg (Leaf): Bolalari yo'q tugun.
- Quyi daraxt (Subtree): Muayyan tugundan boshlanadigan daraxtning bir qismi.
- Balandlik (Height): Ildizdan barggacha bo'lgan eng uzun yo'lning uzunligi.
- Chuqurlik (Depth): Ildizdan ma'lum bir tugungacha bo'lgan yo'lning uzunligi.
Binar Qidiruv Daraxtini JavaScript'da Amalga Oshirish
Node Klassini Aniqlash
Birinchidan, BQD'dagi har bir tugunni ifodalash uchun `Node` klassini aniqlaymiz. Har bir tugun ma'lumotlarni saqlash uchun `key` va o'zining bolalariga `left` va `right` ishoralarini o'z ichiga oladi.
class Node {
constructor(key) {
this.key = key;
this.left = null;
this.right = null;
}
}
Binar Qidiruv Daraxti Klassini Aniqlash
Keyin `BinarySearchTree` klassini aniqlaymiz. Bu klass ildiz tugunini va daraxtga element qo'shish, qidirish, o'chirish va aylanib o'tish uchun metodlarni o'z ichiga oladi.
class BinarySearchTree {
constructor() {
this.root = null;
}
// Metodlar shu yerga qo'shiladi
}
Qo'shish (Insertion)
`insert` metodi BQD'ga berilgan kalit bilan yangi tugunni qo'shadi. Qo'shish jarayoni yangi tugunni mavjud tugunlarga nisbatan tegishli joyga qo'yish orqali BQD xususiyatini saqlab qoladi.
insert(key) {
const newNode = new Node(key);
if (this.root === null) {
this.root = newNode;
} else {
this.insertNode(this.root, newNode);
}
}
insertNode(node, newNode) {
if (newNode.key < node.key) {
if (node.left === null) {
node.left = newNode;
} else {
this.insertNode(node.left, newNode);
}
} else {
if (node.right === null) {
node.right = newNode;
} else {
this.insertNode(node.right, newNode);
}
}
}
Misol: BQD'ga qiymatlarni qo'shish
const bst = new BinarySearchTree();
bst.insert(11);
bst.insert(7);
bst.insert(15);
bst.insert(5);
bst.insert(3);
bst.insert(9);
bst.insert(8);
bst.insert(10);
bst.insert(13);
bst.insert(12);
bst.insert(14);
bst.insert(20);
bst.insert(18);
bst.insert(25);
Qidirish (Searching)
`search` metodi berilgan kalitli tugun BQD'da mavjudligini tekshiradi. U daraxtni aylanib o'tadi, kalitni joriy tugun kaliti bilan taqqoslaydi va shunga mos ravishda chap yoki o'ng quyi daraxtga o'tadi.
search(key) {
return this.searchNode(this.root, key);
}
searchNode(node, key) {
if (node === null) {
return false;
}
if (key < node.key) {
return this.searchNode(node.left, key);
} else if (key > node.key) {
return this.searchNode(node.right, key);
} else {
return true;
}
}
Misol: BQD'dan qiymat qidirish
console.log(bst.search(9)); // Natija: true
console.log(bst.search(2)); // Natija: false
O'chirish (Deletion)
`remove` metodi BQD'dan berilgan kalitli tugunni o'chiradi. Bu eng murakkab operatsiya, chunki tugunni o'chirishda BQD xususiyatini saqlab qolish kerak. Ko'rib chiqilishi kerak bo'lgan uchta holat mavjud:
- 1-holat: O'chiriladigan tugun barg tugun. Shunchaki uni olib tashlang.
- 2-holat: O'chiriladigan tugunning bitta bolasi bor. Tugunni uning bolasi bilan almashtiring.
- 3-holat: O'chiriladigan tugunning ikkita bolasi bor. Tartiblangan vorisni (o'ng quyi daraxtdagi eng kichik tugun) toping, tugunni voris bilan almashtiring va keyin vorisni o'chiring.
remove(key) {
this.root = this.removeNode(this.root, key);
}
removeNode(node, key) {
if (node === null) {
return null;
}
if (key < node.key) {
node.left = this.removeNode(node.left, key);
return node;
} else if (key > node.key) {
node.right = this.removeNode(node.right, key);
return node;
} else {
// kalit node.key ga teng
// 1-holat - barg tugun
if (node.left === null && node.right === null) {
node = null;
return node;
}
// 2-holat - tugunning faqat 1 ta bolasi bor
if (node.left === null) {
node = node.right;
return node;
} else if (node.right === null) {
node = node.left;
return node;
}
// 3-holat - tugunning 2 ta bolasi bor
const aux = this.findMinNode(node.right);
node.key = aux.key;
node.right = this.removeNode(node.right, aux.key);
return node;
}
}
findMinNode(node) {
let current = node;
while (current != null && current.left != null) {
current = current.left;
}
return current;
}
Misol: BQD'dan qiymatni o'chirish
bst.remove(7);
console.log(bst.search(7)); // Natija: false
Daraxtni Aylanib O'tish
Daraxtni aylanib o'tish har bir tugunga ma'lum bir tartibda tashrif buyurishni o'z ichiga oladi. Bir nechta keng tarqalgan aylanib o'tish usullari mavjud:
- In-order: Chap quyi daraxtga, so'ng tugunga, so'ng o'ng quyi daraxtga tashrif buyuradi. Bu tugunlarga o'sish tartibida tashrif buyurishga olib keladi.
- Pre-order: Tugunga, so'ng chap quyi daraxtga, so'ng o'ng quyi daraxtga tashrif buyuradi.
- Post-order: Chap quyi daraxtga, so'ng o'ng quyi daraxtga, so'ng tugunga tashrif buyuradi.
inOrderTraverse(callback) {
this.inOrderTraverseNode(this.root, callback);
}
inOrderTraverseNode(node, callback) {
if (node !== null) {
this.inOrderTraverseNode(node.left, callback);
callback(node.key);
this.inOrderTraverseNode(node.right, callback);
}
}
preOrderTraverse(callback) {
this.preOrderTraverseNode(this.root, callback);
}
preOrderTraverseNode(node, callback) {
if (node !== null) {
callback(node.key);
this.preOrderTraverseNode(node.left, callback);
this.preOrderTraverseNode(node.right, callback);
}
}
postOrderTraverse(callback) {
this.postOrderTraverseNode(this.root, callback);
}
postOrderTraverseNode(node, callback) {
if (node !== null) {
this.postOrderTraverseNode(node.left, callback);
this.postOrderTraverseNode(node.right, callback);
callback(node.key);
}
}
Misol: BQD'ni aylanib o'tish
const printNode = (value) => console.log(value);
bst.inOrderTraverse(printNode); // Natija: 3 5 8 9 10 11 12 13 14 15 18 20 25
bst.preOrderTraverse(printNode); // Natija: 11 5 3 9 8 10 15 13 12 14 20 18 25
bst.postOrderTraverse(printNode); // Natija: 3 8 10 9 12 14 13 18 25 20 15 11
Minimal va Maksimal Qiymatlar
BQD'dagi minimal va maksimal qiymatlarni topish uning tartiblangan tabiati tufayli juda oson.
min() {
return this.minNode(this.root);
}
minNode(node) {
let current = node;
while (current !== null && current.left !== null) {
current = current.left;
}
return current;
}
max() {
return this.maxNode(this.root);
}
maxNode(node) {
let current = node;
while (current !== null && current.right !== null) {
current = current.right;
}
return current;
}
Misol: Minimal va maksimal qiymatlarni topish
console.log(bst.min().key); // Natija: 3
console.log(bst.max().key); // Natija: 25
Binar Qidiruv Daraxtlarining Amaliy Qo'llanilishi
Binar Qidiruv Daraxtlari turli xil dasturlarda qo'llaniladi, jumladan:
- Ma'lumotlar bazalari: Ma'lumotlarni indekslash va qidirish. Masalan, ko'plab ma'lumotlar bazasi tizimlari yozuvlarni samarali topish uchun B-daraxtlar kabi BQD'ning variantlaridan foydalanadi. Ko'p millatli korporatsiyalar tomonidan ishlatiladigan ma'lumotlar bazalarining global miqyosini ko'rib chiqing; ma'lumotlarni samarali olish juda muhimdir.
- Kompilyatorlar: O'zgaruvchilar va funksiyalar haqidagi ma'lumotlarni saqlaydigan belgilar jadvallari.
- Operatsion tizimlar: Jarayonlarni rejalashtirish va xotirani boshqarish.
- Qidiruv tizimlari: Veb-sahifalarni indekslash va qidiruv natijalarini tartiblash.
- Fayl tizimlari: Fayllarni tashkil etish va ularga kirish. Veb-saytlarni joylashtirish uchun global miqyosda ishlatiladigan serverdagi fayl tizimini tasavvur qiling; yaxshi tashkil etilgan BQD asosidagi tuzilma kontentni tezda taqdim etishga yordam beradi.
Ishlash Samaradorligi Masalalari
BQD'ning ishlash samaradorligi uning tuzilishiga bog'liq. Eng yaxshi holatda, muvozanatlangan BQD qo'shish, qidirish va o'chirish amallari uchun logarifmik vaqt murakkabligini ta'minlaydi. Biroq, eng yomon holatda (masalan, qiyshiq daraxt), vaqt murakkabligi chiziqli vaqtga tushishi mumkin.
Muvozanatlangan va Muvozanatlanmagan Daraxtlar
Muvozanatlangan BQD - bu har bir tugunning chap va o'ng quyi daraxtlari balandligi ko'pi bilan birga farq qiladigan daraxtdir. O'z-o'zini muvozanatlovchi algoritmlar, masalan AVL daraxtlari va Qizil-qora daraxtlar, daraxtning muvozanatli bo'lishini ta'minlaydi va barqaror ishlashni kafolatlaydi. Turli mintaqalar serverdagi yuklamaga qarab turli optimallashtirish darajalarini talab qilishi mumkin; muvozanatlash yuqori global foydalanish sharoitida ishlash samaradorligini saqlashga yordam beradi.
Vaqt Murakkabligi
- Qo'shish: O'rtacha O(log n), eng yomon holatda O(n).
- Qidirish: O'rtacha O(log n), eng yomon holatda O(n).
- O'chirish: O'rtacha O(log n), eng yomon holatda O(n).
- Aylanib o'tish: O(n), bu yerda n - daraxtdagi tugunlar soni.
BQD'ning Ilg'or Tushunchalari
O'z-o'zini Muvozanatlovchi Daraxtlar
O'z-o'zini muvozanatlovchi daraxtlar - bu muvozanatni saqlash uchun o'z tuzilishini avtomatik ravishda sozlaydigan BQD'lardir. Bu daraxt balandligining logarifmik bo'lib qolishini ta'minlaydi, bu esa barcha operatsiyalar uchun barqaror ishlashni kafolatlaydi. Keng tarqalgan o'z-o'zini muvozanatlovchi daraxtlarga AVL daraxtlari va Qizil-qora daraxtlar kiradi.
AVL Daraxtlari
AVL daraxtlari har qanday tugunning chap va o'ng quyi daraxtlari orasidagi balandlik farqi ko'pi bilan bir bo'lishini ta'minlash orqali muvozanatni saqlaydi. Bu muvozanat buzilganda, muvozanatni tiklash uchun aylantirishlar amalga oshiriladi.
Qizil-Qora Daraxtlar
Qizil-qora daraxtlar muvozanatni saqlash uchun rang xususiyatlaridan (qizil yoki qora) foydalanadi. Ular AVL daraxtlariga qaraganda murakkabroq, ammo ba'zi holatlarda yaxshiroq ishlash samaradorligini taklif qiladi.
JavaScript Kod Misoli: Binar Qidiruv Daraxtining To'liq Implementatsiyasi
class Node {
constructor(key) {
this.key = key;
this.left = null;
this.right = null;
}
}
class BinarySearchTree {
constructor() {
this.root = null;
}
insert(key) {
const newNode = new Node(key);
if (this.root === null) {
this.root = newNode;
} else {
this.insertNode(this.root, newNode);
}
}
insertNode(node, newNode) {
if (newNode.key < node.key) {
if (node.left === null) {
node.left = newNode;
} else {
this.insertNode(node.left, newNode);
}
} else {
if (node.right === null) {
node.right = newNode;
} else {
this.insertNode(node.right, newNode);
}
}
}
search(key) {
return this.searchNode(this.root, key);
}
searchNode(node, key) {
if (node === null) {
return false;
}
if (key < node.key) {
return this.searchNode(node.left, key);
} else if (key > node.key) {
return this.searchNode(node.right, key);
} else {
return true;
}
}
remove(key) {
this.root = this.removeNode(this.root, key);
}
removeNode(node, key) {
if (node === null) {
return null;
}
if (key < node.key) {
node.left = this.removeNode(node.left, key);
return node;
} else if (key > node.key) {
node.right = this.removeNode(node.right, key);
return node;
} else {
// kalit node.key ga teng
// 1-holat - barg tugun
if (node.left === null && node.right === null) {
node = null;
return node;
}
// 2-holat - tugunning faqat 1 ta bolasi bor
if (node.left === null) {
node = node.right;
return node;
} else if (node.right === null) {
node = node.left;
return node;
}
// 3-holat - tugunning 2 ta bolasi bor
const aux = this.findMinNode(node.right);
node.key = aux.key;
node.right = this.removeNode(node.right, aux.key);
return node;
}
}
findMinNode(node) {
let current = node;
while (current != null && current.left != null) {
current = current.left;
}
return current;
}
min() {
return this.minNode(this.root);
}
minNode(node) {
let current = node;
while (current !== null && current.left !== null) {
current = current.left;
}
return current;
}
max() {
return this.maxNode(this.root);
}
maxNode(node) {
let current = node;
while (current !== null && current.right !== null) {
current = current.right;
}
return current;
}
inOrderTraverse(callback) {
this.inOrderTraverseNode(this.root, callback);
}
inOrderTraverseNode(node, callback) {
if (node !== null) {
this.inOrderTraverseNode(node.left, callback);
callback(node.key);
this.inOrderTraverseNode(node.right, callback);
}
}
preOrderTraverse(callback) {
this.preOrderTraverseNode(this.root, callback);
}
preOrderTraverseNode(node, callback) {
if (node !== null) {
callback(node.key);
this.preOrderTraverseNode(node.left, callback);
this.preOrderTraverseNode(node.right, callback);
}
}
postOrderTraverse(callback) {
this.postOrderTraverseNode(this.root, callback);
}
postOrderTraverseNode(node, callback) {
if (node !== null) {
this.postOrderTraverseNode(node.left, callback);
this.postOrderTraverseNode(node.right, callback);
callback(node.key);
}
}
}
// Foydalanish misoli
const bst = new BinarySearchTree();
bst.insert(11);
bst.insert(7);
bst.insert(15);
bst.insert(5);
bst.insert(3);
bst.insert(9);
bst.insert(8);
bst.insert(10);
bst.insert(13);
bst.insert(12);
bst.insert(14);
bst.insert(20);
bst.insert(18);
bst.insert(25);
const printNode = (value) => console.log(value);
console.log("In-order (tartibli) aylanib o'tish:");
bst.inOrderTraverse(printNode);
console.log("Pre-order (oldindan) aylanib o'tish:");
bst.preOrderTraverse(printNode);
console.log("Post-order (keyin) aylanib o'tish:");
bst.postOrderTraverse(printNode);
console.log("Minimal qiymat:", bst.min().key);
console.log("Maksimal qiymat:", bst.max().key);
console.log("9 ni qidirish:", bst.search(9));
console.log("2 ni qidirish:", bst.search(2));
bst.remove(7);
console.log("7 ni o'chirgandan keyin qidirish:", bst.search(7));
Xulosa
Binar Qidiruv Daraxtlari ko'plab qo'llanilishga ega bo'lgan kuchli va ko'p qirrali ma'lumotlar tuzilmasidir. Ushbu qo'llanma BQD'lar haqida, ularning tuzilishi, operatsiyalari va JavaScript'da amalga oshirilishi haqida to'liq ma'lumot berdi. Ushbu qo'llanmada muhokama qilingan tamoyillar va texnikalarni tushunish orqali butun dunyodagi dasturchilar dasturiy ta'minotni ishlab chiqishda keng ko'lamli muammolarni hal qilish uchun BQD'lardan samarali foydalanishlari mumkin. Global ma'lumotlar bazalarini boshqarishdan tortib, qidiruv algoritmlarini optimallashtirishgacha, BQD haqidagi bilim har qanday dasturchi uchun bebaho boylikdir.
Kompyuter fanlari bo'yicha sayohatingizni davom ettirar ekansiz, o'z-o'zini muvozanatlovchi daraxtlar va ularning turli xil amalga oshirilishlari kabi ilg'or tushunchalarni o'rganish sizning tushunchangiz va imkoniyatlaringizni yanada oshiradi. Binar Qidiruv Daraxtlaridan samarali foydalanish san'atini o'zlashtirish uchun turli stsenariylar bilan amaliyot qilishni va tajriba o'tkazishni davom eting.