Arborele de căutare binar | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Tip de | lemn | |||||||||||||||
Anul inventiei | 1960 | |||||||||||||||
Autor | Andrew Donald Booth | |||||||||||||||
Complexitatea în simbolurile O | ||||||||||||||||
|
||||||||||||||||
Fișiere media la Wikimedia Commons |
Arborele de căutare binar ( ing. arbore de căutare binar , BST) este un arbore binar pentru care sunt îndeplinite următoarele condiții suplimentare ( proprietățile arborelui de căutare ):
Evident, datele de la fiecare nod trebuie să aibă chei pe care operația de comparare este mai mică decât este definită .
De obicei, informațiile care reprezintă fiecare nod sunt o înregistrare, nu un singur câmp de date. Totuși, este vorba despre implementare, nu despre natura arborelui de căutare binar.
În scopuri de implementare, un arbore de căutare binar poate fi definit ca:
Arborele de căutare binar nu trebuie confundat cu heap-ul binar , care este construit după reguli diferite.
Principalul avantaj al unui arbore de căutare binar față de alte structuri de date este posibila eficiență ridicată a implementării algoritmilor de căutare și sortare bazați pe acesta .
Arborele de căutare binar este folosit pentru a construi structuri mai abstracte, cum ar fi seturi , multiseturi , tablouri asociative .
Interfața de bază a arborelui de căutare binară constă din trei operații:
Această interfață abstractă este un caz general, de exemplu, al unor astfel de interfețe luate din probleme de aplicație:
De fapt, un arbore binar de căutare este o structură de date care poate stoca un tabel de perechi (cheie, valoare) și suportă trei operații: FIND, INSERT, REMOVE.
În plus, interfața de arbore binar include trei traversări suplimentare de noduri de arbore: INFIX_TRAVERSE, PREFIX_TRAVERSE și POSTFIX_TRAVERSE. Primul dintre ele vă permite să traversați nodurile arborelui în ordinea cheilor nedescrescătoare.
Dat : arborele T și cheia K.
Sarcină : verificați dacă există un nod cu cheia K în arborele T și, dacă da, returnați un link către acest nod.
Algoritm :
Dat : arborele T și perechea (K, V).
Sarcină : introduceți o pereche (K, V) în arborele T (dacă K se potrivește, înlocuiți V).
Algoritm :
Dat : arborele T cu rădăcina n și cheia K.
Sarcină : eliminați din arborele T un nod cu cheia K (dacă există).
Algoritm :
Există trei operații de parcurgere a nodurilor arborescente care diferă în ordinea în care sunt parcurse nodurile.
Prima operație, INFIX_TRAVERSE, vă permite să traversați toate nodurile arborelui în ordinea crescătoare a tastelor și să aplicați o funcție de apel invers definită de utilizator f fiecărui nod, al cărui operand este adresa nodului. Această funcție funcționează de obicei numai pe perechea (K, V) stocată în nod. Operația INFIX_TRAVERSE poate fi implementată recursiv: mai întâi rulează singur pe subarborele din stânga, apoi rulează funcția dată pe rădăcină, apoi rulează singur pe subarborele din dreapta.
În alte surse aceste funcții sunt numite inorder, preorder, respectiv postorder [1]
Dat : arborele T și funcția f
Sarcină : aplicați f la toate nodurile arborelui T în ordinea crescătoare a tastelor
Algoritm :
În cel mai simplu caz, funcția f poate scoate valoarea perechii (K, V). Când utilizați operația INFIX_TRAVERSE, toate perechile vor fi afișate în ordinea crescătoare a tastelor. Dacă utilizați PREFIX_TRAVERSE, atunci perechile vor fi afișate în ordinea corespunzătoare descrierii arborelui dată la începutul articolului.
Operația „divizarea arborelui după cheie” vă permite să împărțiți un arbore de căutare în două: cu tastele < K 0 și ≥ K 0 .
Operație inversă: există doi arbori de căutare, unul are chei < K 0 , celălalt are chei ≥ K 0 . Îmbină-le într-un singur copac.
Avem doi arbori: T 1 (mai mic) și T 2 (mai mare). Mai întâi trebuie să decideți unde să luați rădăcina: de la T 1 sau T 2 . Nu există o metodă standard, opțiunile posibile sunt:
Este întotdeauna de dorit ca toate căile dintr-un copac de la rădăcină la frunze să aibă aproximativ aceeași lungime, adică ca adâncimea ambelor subarbori din stânga și din dreapta să fie aproximativ aceeași la orice nod. În caz contrar, performanța este pierdută.
În cazul degenerat, se poate dovedi că întregul arbore din stânga este gol la fiecare nivel, există doar arbori din dreapta, caz în care arborele degenerează într-o listă (mergând la dreapta). Căutarea (și, prin urmare, ștergerea și adăugarea) într-un astfel de arbore este egală ca viteză cu căutarea într-o listă și mult mai lentă decât căutarea într-un arbore echilibrat.
Operația de rotație a arborelui este utilizată pentru a echilibra arborele. Virajul la stânga arată astfel:
Întoarcerea la dreapta arată la fel, este suficient să înlocuiți toate stânga cu dreapta în exemplul de mai sus și invers. Este destul de evident că rotația nu rupe ordinea arborelui și are un efect previzibil (+1 sau -1) asupra adâncimii tuturor subarborilor afectați. Algoritmi precum arborele roșu-negru și AVL sunt utilizați pentru a decide ce rotații să efectueze după adăugarea sau eliminarea . Ambele necesită informații suplimentare în noduri - 1 bit pentru roșu-negru sau un număr semnat pentru AVL. Un copac roșu-negru necesită nu mai mult de două ture după adăugare și nu mai mult de trei după îndepărtare, dar cel mai grav dezechilibru poate fi de până la 2 ori (cea mai lungă cale este de 2 ori mai lungă decât cea mai scurtă). Arborele AVL necesită nu mai mult de două rotații după adăugare și până la adâncimea arborelui după ștergere, dar este perfect echilibrat (dezechilibru cu cel mult 1).
Copaci echilibrați:
Arborele (structura de date) | |
---|---|
Arbori binari | |
Arbori binari cu auto-echilibrare |
|
B-copaci |
|
arbori de prefix |
|
Partiționarea binară a spațiului | |
Arbori non-binari |
|
Despărțirea spațiului |
|
Alți copaci |
|
Algoritmi |
Structuri de date | |
---|---|
Liste | |
Copaci | |
Contează | |
Alte |