Extension metodlar oldindan aniqlangan tiplarga yangi metodlarni qo’shish imkoniyatini beradi. Bunday metodlar juda foydali bo’ladi agar bizda klass kodlarini o’zgartirishga imkoniyatimiz bo’lmasa. Yoki bo’lmasa voris olish imkoniyatimiz bo’lmasa, misol uchun klass sealed modifikatori bilan aniqlangan bo’lsa.
Misol uchun biz string tipiga yangi metod qo’shmoqchimiz:
int i = s.DigitsCount();
Console.WriteLine(i);
public static class StringExtension
{
public static int DigitsCount(this string str)
{
int x = str. Count(c => Char.IsDigit(c));
return x;
}
}
Extension metod tuzish uchun oldin static klass yaratib olish kerak, aynan shu klassda extension metod yoziladi. Bizning misolda bu StringExtension. Bu klassga static metod yaratiladi. Bizning misolda bu DigitsCount. Bu metodning vazifasi satrdagi raqamlar sonini aniqlash.
Umuman olganda extension metod bu oddiy static metod, faqat u birinchi parametr sifatida quyidagi ko’rinishida parametr yoziladi: this tip_nomi patametr_nomi, bizning holatda bu
this string str. Bizning extension metodimiz string tipi uchun bo’lgani sababli biz string tipini ishlatamiz.
Endi bu metodni xohlagan satrimizga ishlatimiz mumkin:
int i="nimadir123".DigitsCount();
Birinchi parametrni berish ham shart emas, birinchi parametr sifatida satrni o’zini oladi. Agar qo’shimcha parametr qo’shish kerak bo’lsa ikinchi, uchinchi parametr sifatida ketma-ket qo’shib yozilaveradi:
public static ExtMethod(this int i, int x, int y){ … };
int x =1; x.ExtMethod(1,2);
Windows Presentation Foundation (WPF) - WinForms tizimining analogi, Windows uchun vizual dasturlar tuzish tizimi. WPF tizimi XAML tilidan foydalanuvchi platforma bo’lib, u .NET Frameworkning(3.0 versiyasidan boshlab) qism platformasi hisoblanadi.
WPFni ishlab chiqishdan asosiy g’oya, qiyinchiliklarsiz animatsiyalarga, yorqin ranglarga boy foydalanuvchi interfeysini (bundan keyin “UI” deb yozaman) ishlab chiqishdir.
WPFni WinFormsning evolyutsiyasi desak ham bo’ladi. WPF – video kartadan foydalanuvchi vektorli rendering vositasidir, bu UI ni tezroq va moslashuvchan bo’lishiga yordam beradi.
Nima uchun WPF?
WPF platformasidan foydalanishimizning ko’p sabablari mavjud, ulardan ba’zilari:
· Agar har xil turdagi medialar bilan ishlashingizga to’g’ri kelsa bu platforma yaxshi tanlov
· U WinAPI o’rniga DirectXga asoslanadi. Bu sizga ajoyib grafika va tezlikni taqdim etadi
· U .NETning qism platformasi bo’lganligi sabab shuki, u sizga .NET sinflarining boy kutubxonalaridan foydalanishingizga imkon yaratadi
· WPFda ishlab chiqarilgan dastur mobil telefonlarda ham katta monitorlarda ham ishlata olasiz, chunki u razresheniyaga bog’liq emas
WPFdagi asosiy infro tuzilmalar va turlar
WPFda sinflar 4 xil turga bo’linadi:
· UIElement
· FrameworkElement
· ContentElement
· FrameworkContentElement
Bu sinflar UI modelini tuzish uchun asos hisoblanadi.
WPFda UI daraxt simon ierarxiya ega elementlardan tashkil topgan bo’ladi. Bu daraxt elementlar daraxti deyiladi.
XAML
“XAML” nomlanuvchi bu belgilash tili, UI ni ta’riflashning bir uslubi hisoblanadi.
· Umumiy Dialog oynalar: OpenFileDialog , PrintDialog
· Konteynerlar: ScrollBar, GroupBox
· Maketlar: Grid, DockPanel, StackPanel
· Navigatsiya: Frame, Hyperlink
Boshqaruv elementlarining tashqi ko’rinishini dasturlashsiz shablon va uslublar yordamida o’zgartira olasiz. Va yana bazaviy sinflarga asoslanib, o’z elementingizni yasashingiz mumkin.
WPF o’rnatish
Ushbu havola yordamida Visual Studio muhitini yuklang
C++ - bu kompilyatsiyalanadigan, obyektga yo’naltirilgan dastrulash tili.
Eng mashhur dasturlash tillaridan biri hisoblanadi.
O’tgan asrning 80- yillarida Byorn Straustrup tomonidan ishlab chiqilgan.
C++ eskirdimi?
Bu fikrga qo’shila olmayman. C++ ishlab chiqilgan vaqtlardan boshlab rivojlanib keladi. Bu rivojlanish hali to’xtaganicha yo’q, bunga misol shu yili ham C++20 taqdim etildi.
Kim C++ eskirdi degan fikrda bo’lsa ularga yangilimiz bor – bu til eskirishi uchun biror Texnologik revolyutsiya bo’lishiga to’g’ri keladi ;)
Nima uchun bunday?:
U tez
Dasturlash tillarini samaradorlikga tekshiruvchi xar qanday testni ochsangiz C++ yuqori o’rinlarda turganiga guvoh bo’lasiz. Aynan shu jihati ham IT da C++ ga talabni ko’payishiga sabablaridan biri.
To’g’ri, aytishingiz mumkin bu borada C yoki Rust kabi tillar ham mos keladi deb. Lekin agar siz bitta til o’rganib, unda har qanday qiyinlikdagi dasturlarni tuzmoqchi bo’lsangiz unda sizning tanlovingiz C++.
U universal
C++ kompilyatorlari har qanday operatsion tizimlarda mavjud. Ko’p dasturlar osongina bir platformadan boshqa platformaga ko’chirilishi mumkin, ishchi muhitlar va kutubxonalar bilan sizda muammolar bo’lmaydi.
U qayerda ishlatilishini yodga olishimizning o’zi yuqoridagi gapga isbot bo’la oladi:
mikrokotrollerlar, robotlar, desktop va mobile dasturlar, o’yinlar, statistikalarni qayta ishlash va neyron tarmoqlari. Har joyda.
Ha, hozirgi kunda boshidan oxirigacha C++ da yozilgan dasturlar kam bo’lishi mumkin. Lekin har qanday yirik loyihalar uchun C++ qisman bo’lsa ham ishlatiladi, shuning uchun ham dasturchining tarjimai holida C++ ni bilishi foydadan holi emas.
U faolravishda qo’llab-quvvatlanadi
Qo’llab quvvatlash deganda faqatgina standartlar yangilanishi degani emas. C++ doimiy kutubxonalar, shablonlar va kodlar ulashib turuvchi ajoyib hamjamiyatga ega. C++ yetarlicha qiyin til, shuning uchun yangi boshlaganlarga bunday kutubxonalar, shablonlarning katta yordami tegishi mumkin.
U dasturlashni o’rganish uchun yaxshi fundament bo’la oladi
C++ ni o’rganganingizdan keyin boshqa dasturlash tillarini o’rganish unchaligam qiyinchilik tug’dirmaydi. Bu xuddi mexanik qutilik avtomobildan avtomatik qutilisiga o’tganday, yoki borgan yo’ldan qaytish kabi. Shu sabab ko’p OTM larda C++ kursi mavjud. Misol uchun o’zimizning TATU ;)
Xulosa
Demak C++ hali eskirganicha yo’q va faol ishlatilib kelmoqda.
Eslatib o’taman eng yaxshi, kuchli yoki ideal til mavjud emas. C++ xam ideal emas, kamchiliklarini boshqa safar ko’rib chiqarmiz.
Maqolada biz RegEx(Regular expression) haqida va undan C++ da foydalanish borasida gaplashamiz. Regex ning haqiqiy kuchini kashf qilamiz va bir necha namunalarda ko'rib o'tamiz.
Xo'sh o'zi regex nima? Menimcha bu hozir ko'pchiligimiz uchun yangilik. Regex berilgan belgilar to'plamini ichidan siz bergan ifoda bo'yicha belgilar to'plamini olish. Unchalik tushunarsiz bo'ldimi? Shoshilmang, hozir uni amaliyotda ko'ramiz va u o'ylaymanki sizga yoqib qoladi :) Oddiy bir misol, sizga gap berilgan, o'sha gap ichidan e-mail manzillarini ko'rsatib berishingiz kerak. Qoyil, siz buni qiynalmasdan bajara olasiz! Lekin qanday? Siz beixtiyor harflar va raqamlar aralashgan ifoda(username) va undan keyin keladigan kuchukcha belgisi va domen yozilgan belgilar to'plamini e-mail manzil deb ko'rsatasiz(masalan, cppcoder24@gmail.com) va siz e-mail ni topishda o'z qolipingizdan foydalandingiz(<username>@<domen>). Ya'ni e-mail manzilni qanday formada bo'lishini bilasiz. Endi shuni dasturimizga tatbiq qilib ko'ramiz. Agar siz qidirish tizimlaridan, so'zni qidirish va uni boshqasi bilan almashtirish funksiyalaridan, oddiy matn muxarrirlaridan foydalangan bo'lsangiz, demak siz uni amaliyotda ko'rgansiz! Shuningdek, regex dan parollarni kuchli-kuchsiz tuzilganini tekshirishda ham ishlatishadi. Regex da qidirish belgilardan iborat ifoda yordamida amalga oshiriladi, bu ifoda qolip vazifasini bajaradi.
C++ da kod yozib ko'rganlar juda yaxshi bilishadi, unda ma'lumotlarni to'g'ri ekanligini tahlil qilish bir muncha murakkab jarayon. Masalan, foydalanuvchidan son kiritishni so'radingiz, kiritiladigan narsani siz string da olib, uni haqiqatda sonmi-yo'qmi bilmoqchisiz. Har bir dasturchi bu jarayonda o'zining tekshirish algoritmini yozib chiqishga majbur bo'ladi. Lekin C++ 11 da regex kirib keldi va bu endi muammo emas! C++ 11 ECMAScript, awk, grep va yana bir nechta regular expression grammatikasini qo'llab-quvvatlaydi, biz ECMAScript sintaksisini ko'rib o'tamiz. Regex kutubxonasini kodimizda import qilamiz:
#include <regex>
bu orqali biz regex dan kodimizda foydalana olishimiz mumkin. Lekin bu C++11 va undan yuqorida ishlaydi.
DIQQAT! Namunadagi kodlar main funksiyasi ichiga yoziladi:
#include <iostream>
#include <regex>
using namespace std;
int main()
{
//Namunadagi kodlar
}
Endi c++ da kod yozib, uni sinab ko'rish uchun biror muhitni oching :)
C++ 11 ni sozlash. Sozlashni Code::Blocks muhitida ko'rib o'tamiz. Birorta konsol proyekt ochib, yuqorida turgan paneldan Settings->Compiler ni tanlaymiz. Va uni quyidagi rasmdagidek sozlab olamiz:
Ok ni bosamiz. Tayyor. Dev muhitini ishlatadiganlar diqqatiga. Yuqoridagi paneldan Tools->Compiler Options ga kiramiz, bizga kompilyator sozlamalari oynasi ochiladi:
Va rasmda ko'rsatilgan bo'limdan ISO C++ 11 ni tanlab, OK ni bosamiz, Tayyor
Regex da ifodalar tuzish.
Regex da belgilar to'plamini ichidan o'zimizga kerakli qismini olish uchun ifoda tuzishni o'rganib chiqishimiz kerak. Ifodani belgilar yordamida tuzamiz. Biz tuzgan ifoda o'ziga mosini o'sha belgilar to'plami ichidan topib beradi. Ifodani belgilar to'plamidan tuzamiz, o'z navbatida belgilarimiz oddiy va maxsus(metacharacter) bo'ladi. Oddiy belgilardan foydalansak, ular berilgan matn ichidan o'ziga o'xshaganlarni topib beradi. Maxsus belgilar biroz boshqacharoq ishlaydi. Biz ifodani tuzayotganda uni Raw String qilib tuzganimiz ma'qul. Nima ekanligini keyinroq tushuntirib beraman. Maqolani shu joyiga kelganda, mavzudan biroz chetga chiqib, raw string ni ozroq tushuntirib bersam, Raw string o'zi anglatib turgandek "chala" string. Uni oddiy string tipida qo'shtirnoqlarni boshlanishiga R harfini qo'yib hosil qilamiz, qo'shtirnoq ochilgandan keyin ochiq qavs va yopilishidan oldin yopiq qavs qo'yish shart. Keling, namuna ko'raylik:
string s="Salom!\n Havo ajoyib-a?!";
string s1=R"(Salom!\n Havo ajoyib-a?!)";
cout<<s<<endl;
cout<<"=====\n";
cout<<s1<<endl;
Natija:
Salom!
Havo ajoyib-a?!
=====
Salom!\n Havo ajoyib-a?!
Ko'rib turganingizdek, \n da enter tashlanishi kerak edi, raw string esa shunaqa joylarini inkor qila oladi
\ - bu shunchaki backslash va uni raw stringda shunchaki ishlatish mumkin, stringda backslash ni ishlatish uchun \\ yozishimiz kerak.
Ifodamiz albatta regex tipida bo'lishi kerak. Ifoda yozishdan oldin ba'zi metacharacterlar(maxsus belgilar) bilan tanishib chiqsak:
. - nuqta har qanday belgini topib beradi
\d - har qanday raqamni topib beradi(decimal). Ushbu metacharacterga ekvivalent: [[:digit:]]
\D - \d ni teskarisi, raqam bo'lmagan belgini topib beradi. Ushbu metacharacterga ekvivalent [^[:digit]]
\s - bo'shliqni topadi(space, tab)
\S - \s ni teskarisi.
\w - alphanumeric(harf yoki raqam) va tagchiziq belgisini topadi.
\W - \w ni teskarisi.
+ biror x belgidan keyin ushbu belgini qo'yish orqali ushbu x belgi 1 yoki ko'p marta qatnashishi kerakligini bildirgan bo'lamiz.
| - or(yoki), buni biz 2 ta belgi orasiga qo'llash orqali ulardan biri kelganini aniqlashimiz mumkin bo'ladi.
[belgilar to'plami] - ushbu burchakli qavslar ichida belgilar kategoriyasini kiritamiz. Ichidagi belgilardan duch kelganini topadi. Masalan, agar [abc] desak, unda a, b, yoki c belgisini topadi.
X dan Y gacha bo'lgan oraliqlarni [X-Y] tarzida belgilaymiz. Masalan: [a-z] - a, b, c, d, ... z belgilar ichidan uchraganini topib beradi, agar [0-9] desak, unda raqamlarni topadigan bo'ladi.
regex_match(string s, match m, regex rgx) - matndan ifodaga mos qismini qidiradi, topilsa true, aks holda false qaytaradi. Parametrlariga ortiqcha izoh berishim shartmas deb o'ylayman - 3 ta argument oladi, biri string tipida, 2-si regex bo'lishi kerak. m argumenti haqida keyinroq gaplashamiz, hozircha u unchalik muhimmas va argument berilishi shartmas.
Maxsus belgilar bilan biroz bo'lsa-da tanishib oldik. Ho'p, bu yaxshi, lekin men matn ichidan aytaylik nuqta(.) ni qidirmoqchiman, lekin u metacharacter bo'lsa, unda buni qanday qilaman? Biz maxsus belgilarni oldiga backslash qo'yish orqali ularni maxsus qobilyatidan maxrum qilib qo'yamiz, javob: \. orqali nuqtani topishimiz mumkin.
Maxsus belgilardan qanday foydalanishni esa quyidagi misolda ko'rib o'tamiz:
Aytaylik, sizga string tipida ma'lumot berilgan, ushbu ma'lumotni int tipiga o'girishda xatolik bo'lish-bo'lmasligini topishingiz kerak. Kiritiladigan ifodalar masalan 007, +07, 7 yoki -007, -7 ko'rinishida bo'lishi mumkin. +-12 kiritsak xatolik beradi. Endi asosiy fokusni kod yozishga qaratamiz, regex da o'rgangan ayrim metacharacterlarimiz yetarli:
Menimcha ko'pchilik regex tipidagi ifodamizga unchalik tushunmadi, uni bo'laklab tahlil qilamiz. Raw string ligi uchun biz R"()" ichiga ifodani yozamiz. Endi, son oldida + yoki - kelishi kerak, buni qavs ichida (+|-) deb yozishimiz mumkin edi, lekin biz + ni metacharacter ekanligini hisobga olib, uni maxsus qobilyatidan maxrum qilamiz: (\+|-) bo'ldi. ? belgisi 0 yoki 1 marta qatnashsin degani, uni boyagi tuzgan ifodamizdan keyin qo'llasak, + yoki - belgisi 0 yoki 1 marta qatnashsin degan bo'lamiz. [0-9] esa 0 dan 9 gacha kelgan raqam degani, undan keyin agar + qo'ymasak, u faqat bir xonali sonlar uchun ishlaydi. [0-9]+ ifodamiz 0 dan 9 gacha oraliqdagi raqamlar 1 yoki ko'p marta qatnashsin deganini ifodalaydi. Endi barchasini umumlashtiramiz: (\+|-)?[0-9]+ --> + yoki - belgisi 0 yoki 1 marta qatnashgan holda 0 dan 9 gacha bo'lgan raqam 1 yoki ko'p marta bo'lsin. Hozir bularni o'qib, bu AbraKadabraga tushunmadingizmi? Unda o'zingiz metacharacterlar tasnifiga qarab boshqattan hijjalab tahlil qilib ko'ring.
Metacharacterlarga yaxshi e'tibor berganlar fahmlab ulgurishgan: [0-9] ni [\d] bilan almashtirishimiz mumkin, bu natijaga ta'sir qilmaydi. \d nima qilishini yuqoridan topishingiz mumkin.
ifoda o'zgaruvchisiga regex da ifodamizni yozmasdan, uni shundayligicha regex_match funksiyamizga berib qo'ysak ham bo'laveradi:
regex_match(input, regex(R"((\+|-)?[0-9]+)"))
Endi biroz kirishib oldik deb o'ylayman, shu joyida raw string ni nega qo'llayotganimizga qisqacha izoh berib ketsam. C++ da shunchaki oddiy string ga regex ifodasini kiritsak u xunuklashib ketadi. Keling, ifoda o'zgaruvchisidagi scriptimizni oddiy stringga o'giramiz: (\\+|-)?[0-9]+ Nega 2 ta backslash? Yuqorida aytganimdek, backslashni o'zini stringga berish uchun \\ ni yozish kerak. Ho'p, bunda bitta backslashga farq qilyabdi ifodamiz, lekin agar ko'p marta maxsus belgilarni oddiy belgi sifatida ifodamizga kiritmoqchi bo'lsak-chi? Unda ularni oldiga backslash qo'yishimiz kerak ularni maxsus qobilyatini bekor qilish uchun, keyin shu backslashni o'ziga ham yana bitta backslash qo'llashimiz kerak, bu o'qishni birmuncha qiyinlashtiradi, tinchgina raw stringdan foydalanib qo'yaveraylik ;)
Endi e-mail uchun regex ifoda yozib ko'ramiz:
regex pattern_email(R"(([\w\.-]+)@([\w\.-]+))"
Endi tahlil qilib ko'rsak: ([\w\.-]+)@([\w\.-]+) ifodamizni to'lig'i. 1-qavsda kelgan burchakli qavs ichida biz belgilar kategoriyamizni tuzdik: \w - harf yoki raqam, \. - nuqta(agar oddiy nuqta bo'lsa maxsus qobiliyatidan foydalanib qo'yadi :) ), chiziqcha(- bir o'zi oddiy belgi bo'lib keladi, oraliqlarda boshqacha), Shulardan keyin kuchukcha va yana boyagi ifodamiz. Bu orqali yuqorida o'ylab qo'ygan <username>@<domen> qolipimizni yaxshiroq tushuntirdik.
Regex da ba'zi funksiyalar.
Ifoda tuzishni biroz o'rganib oldik, endi ba'zi funksiyalarni ko'rib o'tsak.
regex_match() - ushbu funksiya haqida yuqorida aytib o'tgandim. m argumentiga kelsak, u berilayotgan belgilar to'plami string yoki char massiv shaklida bo'lishiga qarab smatch yoki cmatch tipida bo'ladi, o'ziga ifoda bo'yicha topilgan ma'lumotni oladi, masalan:
agar mystr char massiv bo'lsa, mch o'zgaruvchisining tipi cmatch bo'lishi kerak.
smatch/ cmatch ni shunchaki chop etolmaysiz, buning uchun chiqarish operatorini qayta yuklashga to'g'ri keladi. Yaxshisi, sikldan foydalaning, yoki nom.str() qilib ko'ring, bunda nom smatch/cmatch tipidagi o'zgaruvchi
regex_search(s, m, rgx) - bu ham xuddi match ga o'xshaydi, berilgan satr ichidan rgx ifodaga mosini qidiradi, agar bo'lsa uni m ga beradi.
regex_replace() - 3 ta argument oladi: birorta matn, regex ifoda, va almashtiriladigan so'z. Matnda ifodaga mos belgilar bo'lsa, ularni almashtiriladigan so'z bilan almashtirib qaytaradi. Namuna:
ifodamizda [0-9] ni tushundingiz, {9,12} - shakli: {x, y}, o'zidan oldin kelgan belgini minimal x marta, maksimal y marta takrorlanishi kerakligini bildiradi, ifodamizda esa o'sha 0-9 gacha raqamlar minimal 9 marta, maksimal 12 marta qatnashsin degani. Agar biz uni shunchaki {9,} qilsak, unda kamida 9 marta qatnashsin degani bo'ladi.
Yuqoridagi namuna telefon raqamlar uchun yana ozroq mukammallashtirishingiz mumkin bo'ladi, masalan \+?9989[01349][0-9]{7} qilib. E'tibor qilgan bo'lsangiz, yuqorida {9,} ifodasi birorta belgi kamida 9 marta qatnashsin deganini bildiradi degandik. bunda esa {7} faqat 7 marta qatnashsin degani, vergulga e'tibor bering.
regex_iterator() - keling, buni ko'rishdan oldin quyidagi matnni tahlil qilib ko'ramiz: "Men kecha o'zimning e-mailim emailnom@gmail.comdan support@gmail.comga xat yubordim" matnidagi barcha email larni oladigan dastur tuzaylik. Buni regex_search bilan eplasa bo'ladi dersiz, lekin u qolipga tushadigan ma'lumotlarni birinchisini oladi-da, bizga hammasi kerak! Balkim, sikl yordamida regex_search, regex_match va regex_replace larni qo'llamoqchidirsiz, yomonmas. Lekin regex_iterator bilan kodlash bu ishda oson (iterator - takrorlovchi degani)! regex_iterator char massiv bilan ishlash uchun, string bilan esa sregex_iterator ishlaydi. Biz string da ish ko'ramiz, sababi string bilan ishlashda C-string(const char *) ga qaraganda bir qancha ustunlik tomonlari bor, shuning uchun namunani sregex_iterator da ko'rib o'tamiz. Biz har bir topilgan ma'lumotni chop etishimiz uchun sikldan foydalanamiz, faqat bunda sanagichimiz sregex_iterator turida bo'ladi. Har doimgidek namuna kodini ko'rsataman, so'ng uni tahlil qilamiz:
3-qatordan boshlasak. Tahlil qilinishi kerak bo'lgan matn stringda, shuning uchun sregex_iterator dan foydalanamiz. Shu tipda it degan o'zgaruvchi olyabmiz, u matnimiz boshidan oxirigacha regexp qolipimiz bo'yicha ma'lumot qidiradi. Umuman olganda, iteratorni pointer bilan umumiy xususiyatlari ko'p, lekin bir muncha murakkab. Siz uni xuddi pointer kabi oshirishingiz mumkin. sregex_iterator va regex_iterator ning o'ziga xos xususiyati shunda-ki, ushbu tiplarda o'zgaruvchi e'lon qilsangiz va unga hech narsani o'zlashtirmasangiz, u avtomatik ravishda oxiriga o'tdi deb qaraladi. 3-qatordagi iteratorga qarshi 4-qatordagisini sinab ko'ramiz: ular bir-biriga teng bo'lguncha it o'zgaruvchisini smatchga o'zlashtirib chop etamiz, it ni bittaga oshiramiz, va ekranda e-mail manzillarni ko'rishimiz mumkin!
Daraxt - bu uning har bir tuguni nol yoki bir- necha bolaga ega bo‘lgan iyerarxik tuzilmadir.
Daraxt tuzilmasi quyidagi ko‘rinishda bo‘lishi mumkin:
Bu daraxt oila tuzilmasini ifoda etmoqda. Daraxt tugunlari odamlarni ifodalamoqda, chiziqlar esa ular orasidagi bog‘lanishni. Bu turdagi maʼlumotlarni saqlash uchun daraxt tuzilmasi eng qulay tuzilma hisoblanadi.
Ikkilik (Binar) daraxt
Binar daraxt yuqorida ko‘rsatilgan daraxtga o‘xshaydi, lekin baʼzi qoidalarga asosan quriladi:
Har bir tugundagi bolalar soni 2 tadan oshmasligi zarur
Xar qanday tugun qiymatidan kichik bo‘lgan qiymat chap farzandga yoki chap farzandning chap farzandiga yoziladi
Xar qanday tugun qiymatidan katta bo‘lgan qiymat o‘ng farzandga yoki ong farzandning o‘ng farzandiga yoziladi
Keling shu qoidalar asosida qurilgan daraxtni ko‘raylik:
Ahamiyat bering, bosh tugun (8)dan chapdagi barcha elementlarning qiymatlari sakkizdan kichik undan o‘ngdagisi esa sakkizdan katta. Bu qoidalar daraxtning xar bir tuguniga tegishli.
Keling daraxt bo‘sh bo‘lgandan boshlab qanday qurilganini qarab chiqamiz. Birinchi navbatda 8 ni qo‘shamiz. Dastlab daraxt bo‘sh bo‘lgani sabab u bosh tugun hisoblanadi. Undan keyin 4 ni qo‘shamiz. 8 dan 4 kichik bo‘lgani uchun tepadagi qoidalarga amal qilgan xolda 4 ni 8 ning chap tomoniga yozamiz. 8 ning hech qanday farzandi bo‘lmagani uchun 4 shu joyda qoladi.
Endi 2 kiritamiz. Maʼlumki 2 dan 8 katta, shu sabab chapga yuramiz. Chapda allaqachon qiymat borligi sabab chap farzand qiymati 2 bilan solishtiriladi. Chap farzandning qiymati (4) 2 dan kata bo‘lgani sabab 4 ning chap tomoni qaraladi. 4 ning chap tomonida element bo‘lmagani sabab 2 shu joyga joylashtiriladi. Shunday qilib kiritilgan xar bir element uchun yuqoridagi solishtiruvlar qaytariladi.
Daraxtdan element olib tashlash
Daraxt elementini o‘chirish oddiy tuyulishi mumkin, lekin hisobga olish kerak bo‘lgan holatlari mavjud.
Algoritmning umumiy ko‘rinishi quyidagicha:
Qiymatga mos elementni topish
Uni o‘chirish
Biz berilgan qiymatga mos qiymatni topganimizdan keyin biz 3- xil holatga duch kelishimiz mumkin.
1 – Holat: O‘chirilishi lozim bo‘lgan elementning o‘ng farzandi mavjud emas.
Bu holatda biz, shunchaki chap farzandni o’chirilgan element o’rniga ko’chiramiz. Natijada yuqoridagi daraxt quyidagi ko’rinishga keladi:
2 – Holat: O’chirilishi lozim bo’lgan elementning faqat o’ng farzandi mavjud va o’z navbatida bu farzandning chap tomonida element mavjud emas.
Bu holatda o’chirilgan element o’rniga o’ng farzand (6) ko’chiriladi. Natijada daraxt quyidagi ko’rinishga keladi:
3 – Holat: O’chirilayotgan elementning o’ng farzandi mavjud va bu farzandning chap farzandi mavjud:
Bu holatda o‘chirilgan element o‘rinini eng chapdagi element egallaydi yaʼni 6. Bunga sabab element o‘chirilganda tuzilma o‘z xususiyatlarini saqlab qolishi zarur yaʼni tugunning chap tomonida undan kichik, o‘ng tomonida esa undan katta qiymat joylashishi kerak. Natija:
Shunday qilib biz siz bilan binar daraxtdagi eng asosiy ikkita daraxt qurish va undan element o’chirish jarayonlarini o’rgandik.