Binarno stablo pretrage veličine 9 i dubine 3, sa korenom 8 i listovima 1, 4, 7 i 13
U informatici, **binarno stablo pretrage** (**BSP**), poznato i kao **sortirano binarno stablo**, je binarno stablo zasnovano na čvorovima, gde svaki čvor ima uporedljivi ključ (sa dodeljenom vrednošću) i zadovoljava uslov da je vrednost svakog čvora veća od vrednosti svakog čvora u njegovom levom podstablu i manja od vrednosti svakog čvora u njegovom desnom podstablu. Svaki čvor ima najviše dva deteta. Svako dete mora da bude ili list (nema nijedno dete) ili koren još jednog binarnog stabla pretrage. BSP je dinamička struktura podataka, i veličina BSP-a je ograničena samo količinom slobodne memorije u operativnom sistemu. Najveća prednost binarnog stabla pretrage je da ostaje uređeno, što omogućava brže vreme pretrage nego večina drugih struktura. Osnovna svojstva binarnog stabla pretrage:

* Levo podstablo čvora sadrži samo čvorove koje imaju manju vrednost od njega.
* Desno podstablo čvora sadrži samo čvorove koje imaju veću vrednost od njega.
* Levo i desno podstablo moraju takođe biti binarna stabla pretrage.
* Svaki čvor može imati najviše 2 deteta.
* Ne smeju postojati duplikati čvorova.
* Postoji jedinstven put od korena do svakog čvora.

Najveća prednost binarnog stabla pretrage u odnosu na ostale strukture podataka je da algoritmi sortiranja i algoritmi pretrage kao npr. pretraga u dubinu (in-order) mogu biti veoma efikasni. Ostale prednosti su:

* Binarno stablo pretrage ima brzo ubacivanje i brisanje elemenata kada je balansirano.
* Kod je jednostavniji nego kod ostalih struktura podataka.
* Čuva ključeve u čvorovima na takav način da se pretraga, ubacivanje i brisanje elemenata može uraditi efikasno.
* Veoma jednostavna implementacija.
* Čvorovi u stablu su dinamički po prirodi.

Binarno stablo pretrage je fundamentalna struktura podataka pomoću koje se konstruišu apstraktnije strukture podataka kao npr. skupovi, multiskupovi i asocijativni nizovi. Neki od nedostataka su:

* Oblik binarnog stabla pretrage zavisi samo od reda ubacivanja elemenata, i može biti degenerisano.
* Kada ubacujemo ili tražimo element u binarnom stablu pretrage, ključ svakog posećenog čvora mora da se uporedi sa ključem elementa kog ubacujemo ili tražimo.
* Ključevi u binarnom stablu pretrage mogu biti dugački, što može uticati na vremensku složenost.

Provera da li je stablo BSP ili nije
------------------------------------

  

Ponekad imamo binarno stablo, i potrebno je odrediti da li je ono BSP. Ovo je zanimljiv problem koji ima jednostavno rekurzivno rešenje.

BSP svojstvo--svaki čvor u desnom podstablu mora da bude veći od trenutnog čvora i svaki čvor u levom podstablu mora da bude manji (ili jednak) od trenutnog čvora--je ključna stvar pomoću koje određujemo da li je stablo BSP ili nije. Na prvi pogled, izgleda kao da je dovoljno samo da obiđemo stablo, proverimo da li svaki čvor sadrži vrednost koja je veća od vrednosti njegovog levog deteta i manja od vrednosti njegovog desnog deteta, i ako ovo tvrđenje važi za svaki čvor u stablu, onda je to BSP. Ovo je takozvani "Pohlepni pristup". Ali, očigledno je da ovaj pristup neće raditi za sledeće stablo: 

```
     20
    /  \
  10    30
       /  \
      5    40
```

I navedenom stablu, svaki čvor zadovoljava uslov da sadrži vrednost veću od njegovog levog deteta a manju od desnog, ali ipak, to nije BSP: vrednost 5 je u desnom podstablu čvora koji sadrži 20, što nije u skladu sa svojstvom BSP.

Kako rešiti ovo? Ispostavlja se da umesto da donesemo odluku zasnovanu isključivo na vrednosti čvora i njegove dece, potrebne su nam informacije koje potiču i od roditelja. U prethodnom primeru, kada bismo zapamtili čvor sa vrednošću 20, videli bismo da čvor sa vrednošću 5 ne zadovoljava uslove BSP.

Tako da, uslovi koje treba da proverimo za svaki čvor su: a) ako je čvor levo dete svog roditelja, onda mora biti manji (ili jednak) od roditelja i mora da prenese vrednost od svog roditelja svom desnom podstablu da bi bili sigurni da nijedan od čvorova u tom podstablu nije veća od roditelja, i slično b) ako je čvor desno dete svog roditelja, onda mora biti veće od svog roditelja i mora da prenese vrednost od svog roditelja svom levom podstablu da bi bili sigurno da nijedan od čvorova u tom podstablu nije manji od roditelja.

Jednostavno, ali elegantno rekurzivno rešenje u Javi, može da objasni ovo malo bolje:

```
   public static boolean isBST(TreeNode node, int leftData, int rightData)
   {
   if (node == null)
       return true;
   
   if (node.getData() > leftData || node.getData() <= rightData)
       return false;
   
   return (isBST(node.left, node.getData(), rightData) && isBST(node.right, leftData, node.getData()));
   }
```

Poziv ove funkcije može izgledati ovako:

```
   if(isBST(root, Integer.MAX_VALUE, Integer.MIN_VALUE))
        System.out.println("This is a BST.");
   else
        System.out.println("This is NOT a BST!");
```

Razlike između binarnog stabla i binarnog stabla pretrage
---------------------------------------------------------

  

Binarno stablo: Ukratko, binarno stablo je stablo kod koga svaki čvor ima dva najviše dva deteta. U binarnom stablu, levo i desno dete mogu imati vrednosti nezavisne od vrednosti roditelja. 

```
    3
  /   \
 4     5
```

Binarno stablo pretrage: Kod binarnog stabla pretrage, levo dete sadrži vrednost manju od roditelja, a desno dete sadrži vrednost koja je veća od vrednosti roditelja. 

```
    4
   / \
  3   5
```

Operacije
---------

Operacije, kao što su ***pretraga***, kod binarnog stabla zahtevaju poređenje između čvorova. Ova poređenja se obavljaju sa pozivima funkciji *komparatora*. *Komparator* može biti definisam implicitno ili eksplicitno, u zavisnosti od jezika u kome je implementirano binarno stablo pretrage. can be explicitly or implicitly defined, depending on the language in which the binary search tree was implemented. Čest *komparator* je manje od funkcije, na primer, *a* < *b*, gde su *a* i *b* ključevi dva čvora *a* i *b* u binarnom stablu pretrage.

### Pretraga

Pretraga binarnog stabla pretrage za određenim ključem može se uraditi rekurzivno ili iterativno. 

Počinjemo sa korenim čvorem. Ako je stablo *null*, onda ključ koji tražimo ne postoji u stablu. Ako je ključ jednak korenu, onda je pretraga gotova i vraćamo čvor. Ako je ključ manji od vrednosti korena, onda pretražujemo levo podstablo. Slično tome, ako je ključ veći od korena, pretražujemo desno podstablo. Ovaj proces se ponavlja sve dok ne pronađemo ključ ili preostalo podstablo ne postane *null*. Ako ključ nije pronađen pre nego što dođemo do *null* podstabla, onda taj ključ ne postoji u stablu. Ovo se lako radi sa rekurzivnim algoritmom:

```
**function** Find-recursive(key, node):  *// call initially with node = root*
    **if** node = Null **or** node.key = key **then**
        **return** node
    **else if** key < node.key **then**
        **return** Find-recursive(key, node.left)
    **else**
        **return** Find-recursive(key, node.right)
```

Isti algoritam se može implementirati iterativno:

```
**function** Find(key, root):
    current-node := root
    **while** current-node **is not Null do**
        **if** current-node.key = key **then**
            **return** current-node
        **else if** key < current-node.key **then**
            current-node := current-node.left
        **else**
            current-node := current-node.right
    **return Null**
```

U najgorem slučaju, ovaj algoritam mora da traži od korena stabla do lista najdaljeg od korena, tako da operacija pretrage traje proporcijalno *visini* stabla. U proseku, binarno stablo pretrage sa *n* čvorova ima visinu O (log *n*). Ali, u najgorem slučaju, visina može biti i O(*n*).

### Ubacivanje elementa

Ubacivanje elementa počinje isto kao i pretraga; ako ključ nije jednak korenu, pretražujemo levo ili desno podstablo ka malopre. Na kraju dolazimo do eksternog čvora i dodajemo novu ključ-vrednost (ovde kao 'newNode') kao njegovo levo ili desno dete, u zavisnosti od vrednosti čvora.

Evo kako izgleda tipično dodavanje elementa u binarno stablo pretrage u jeziku C++:

```
void insert(Node\*& root, int data) {
 if (!root) 
 root = new Node(data);
 else if (data < root->data)
 insert(root->left, data);
 else if (data > root->data)
 insert(root->right, data);
 return;
}

```

Navedena *destruktivna* funkcija modifikuje stablo u mestu. Nakon njenog izvršavanja, izgubiće se prethodna verzija stabla. Druga mogućnost je da, kao u sledećem primeru u jeziku Python, rekonstruišemo sve pretke ubačenog čvora; svaka referenca na originalno stablo ostaje validna, i tako je stablo *stalna struktura podataka*:

```
 def binary\_tree\_insert(node, key, value):
     if node is None:
         return TreeNode(None, key, value, None)
     if key == node.key:
         return TreeNode(node.left, key, value, node.right)
     if key < node.key:
         return TreeNode(binary\_tree\_insert(node.left, key, value), node.key, node.value, node.right)
     else:
         return TreeNode(node.left, node.key, node.value, binary\_tree\_insert(node.right, key, value))

```

  

Ubacivanje elementa u BSP, zahteva vreme proporcionalno visini stabla u najgorem slučaju, a to je O(*n*). U prosečnom slučaju, složenost je O(log *n*).

### Brisanje elementa

Postoje tri slučaja koje treba razmotriti: 

* **Brisanje lista (čvora bez dece):** Brisanje lista je lako, samo ga izbacujemo iz stabla.
* **Brisanje čvora sa jednim detetom:** Briše se čvor, i zamenjuje sa svojim detetom.
* **Brisanje čvora sa oba deteta:** Neka se čvor koji brišemo zove *N*. Ne brišemo *N*. Umesto toga, biramo njegovog in-order sledbenika, ili njegovog in-order prethodnka, *R*. Kopiramo vrednost *R* u *N*, i rekurzivno pozovemo brisanje na *R* dok ne dođemo do nekog od prva dva slučaja.

Čvorovi sa decom su teži za brisanje. Kao sa svim binarnim stablima, in-order sledbenik čvora je najlevlji čvor u njegovom desnom podstablu, a njegov in-order prethodnik je najdešnji element u njegovom levom podstablu. Brišemo ga u slkadu sa jednim od dva jednostavina slučaja iznad.

Brisanje čvora sa dva deteta iz binarnog stabla pretrage. Prvo nadjemo najdešnji čvor u levom podstablu, in-order prethodnik **6**. Kopiramo tu vrednost u čvor koji treba da obrišemo. In-order prethodnik se onda može lako obrisati, zato što ima najviše jedno dete. Isti metod radi simetrično za in-order sledbenika **9**.
Ukoliko često koristimo in-order sledbenika ili in-order prethodika za svaki slučaj sa dva deteta, može doći do nebalansiranog stabla, tako da neke implementacije biraju jedan od ta dva slučaja u različitim trenucima.

```
def find\_min(self): # Gets minimum node (leftmost leaf) in a subtree
    current\_node = self
    while current\_node.left\_child:
        current\_node = current\_node.left\_child
    return current\_node

def replace\_node\_in\_parent(self, new\_value=None):
    if self.parent:
        if self == self.parent.left\_child:
            self.parent.left\_child = new\_value
        else:
            self.parent.right\_child = new\_value
    if new\_value:
        new\_value.parent = self.parent

def binary\_tree\_delete(self, key):
    if key < self.key:
        self.left\_child.binary\_tree\_delete(key)
    elif key > self.key:
        self.right\_child.binary\_tree\_delete(key)
    else: # delete the key here
        if self.left\_child and self.right\_child: # if both children are present
            successor = self.right\_child.find\_min()
            self.key = successor.key
            successor.binary\_tree\_delete(successor.key)
        elif self.left\_child:   # if the node has only a \*left\* child
            self.replace\_node\_in\_parent(self.left\_child)
        elif self.right\_child:  # if the node has only a \*right\* child
            self.replace\_node\_in\_parent(self.right\_child)
        else: # this node has no children
            self.replace\_node\_in\_parent(None)

```

### Obilazak stabla

Kada je binarno stablno kreirano, možemo vratiti njegove elemente in-order, rekurzivnim obilaskom levog podstabla čvora, pristupom samom čvoru, i onda rekurzivnim obilaskom desnog podstabla čvora, zatim nastavljajući ovaj šablon za svaki čvor nakon što mu rekurzivno pristupimo. Kao sa svim binarnim stablima, imamo i pre-order i post-order obilazak, ali nijedan nije koristan za binarno stablo pretrage. In-order obilazak će uvek vratiti sortiran niz elemenata čvora.

Kod za in-order obilazak u jeziku Python:

```
def traverse\_binary\_tree(node, callback):
    if node is None:
        return
    traverse\_binary\_tree(node.leftChild, callback)
    callback(node.value)
    traverse\_binary\_tree(node.rightChild, callback)

```

Obilazak je složenosti O(*n*) , zato što se mora obići svaki čvor. 

### Sortiranje

Binarno stablo pretrage se može iskoristiti za implementaciju jednostavnog, ali efikasnog algoritma za sortiranje. Slično kao kod heap sort-a, ubacujemo sve vrednosti koje želimo da sortiramo u novu strukturu podataka, u ovom slučaju binarno stablo pretrage, i onda ga obiđemo in-order obilaskom, i dobijamo rezultat:

```
def build\_binary\_tree(values):
    tree = None
    for v in values:
        tree = binary\_tree\_insert(tree, v)
    return tree

def get\_inorder\_traversal(root):
 '''
 Returns a list containing all the values in the tree, starting at \*root\*.
 Traverses the tree in-order(leftChild, root, rightChild).
 '''
    result = []
    traverse\_binary\_tree(root, lambda element: result.append(element))
    return result

```

Najgori slučaj `build_binary_tree` je {\displaystyle O(n^{2})}—ako mu damo sortirani niz vrednosti, on ih ulanča u povezanu listu bez levog podstabla. Na primer, `build_binary_tree([1, 2, 3, 4, 5])` stvara stablo tree `(1 (2 (3 (4 (5)))))`.

Postoji nekoliko načina za izbegavanje ove mane sa jednostavnim binarnim stablima; najčešća je samobalansirajuće binarno stablo pretrage. Ako uradimo istu proceduru koristećo takvo stablo, najgora složenost je O(*n*log *n*).

Vrste
-----

Postoji mnogo vrsta binarnih stabla pretrage. AVL-stabla i Crveno-crna stabla su oblici samobalansirajućeg binarnog stabla pretrage. Rašireno stablo je binarno stablo pretrage koje automatski pomera elemente kojima se često pristupa bliže korenu. U Treap-u (*heap stablo*), svaki čvor čuva i (nasumično izabran) prioritet i roditeljski čvor ima viši prioritet od svoje dece. Tango stablo su stabla optimizovana za brzu pretragu.

Druga dva prideva koja opisuju binarno stablo pretrage su *kompletno* i *degenerisano* stablo.

Kompletno binarno stablo je binarno stablo koje je skroz puno, sa mogućnošću izuzetka donjeg nivoa, koje je napunjeno sa leva na desno. U kompletnom binarnom stablu, svi čvorovi su najlevlje moguće. To je stablo sa n nivoa, gde za svaki nivo d <= n - 1, broj postojećih čvorova na nivou d je jednak 2d. Ovo znači da svi mogući čvorovi postoje na ovim nivoima. Dodatan uslov za kompletno binarno stablo je da za n-ti nivo, svi postojeći čvorovi moraju da budu popunjeni s leva na desno.

Degenerisano stablo je stablo gde za svaki roditeljski čvor, postoji samo jedno dete čvor. Ono je nebalansirano i, u najgorem slučaju, performanse se spuštaju na nivo povezane liste. Ako funkcija za dodavanje čvora ne podržava rebalansiranje, onda se lako može stvoriti degenerisano stablo ako mu dodajemo podatke koji su već sortirani. Ovo znači da u merenju performansi, stablo će se na kraju ponašati kao povezana lista.

### Poređenje performansi

D. A. Heger (2004) je objavio poređenje performansi binarnih stabla pretrage. Treap ima najbolje performanse u proseku, dok Crveno-crna stabla ima najmanje variajcija u performansama. 

### Optimalno binarno stablo pretrage

Rotacija stabla je veoma česta interna operacija u binarnim stablima, da bi se održao savršen ili blizak-savršenom, interni balans u stablu.
Ako ne želimo da modifikujemo stablo pretrage, i znamo tačno koliko često će se pristupati svakom elementu, možemo da konstruišemo  *optimalno binarno stablo pretrage*, stablo pretrage kod koga je prosečna cena potraživanja elementa minimalizovana.

Ako ne znamo unapred kojim redom će se pristupati elementima stabla, možemo da koristimo Rašireno drvo.

  

  

**Primer u Python-u:**

import sys
import random

1. random list generator

def random\_list (min, max, elements):

```
   list = random.sample(range(min, max), elements)
   return list
```

1. class for nodes

class Node :

```
   def __init__(self, data) :
       self.p = None
       self.r = None
       self.l = None
       self.data1 = data   
       self.data2 = str(data)
```

1. tree class

class Tree :

```
   #root is only field
   
   #constructor
   def __init__(self) :
       self.root = None
```

```
   #method for adding nodes to tree
   def add(self, val) : #same as insert method from PDF
       if(self.root == None) :
           self.root = Node(val)
       else :
           self._add(val, self.root)
```

```
   #side method for recursive adding
   def _add(self, val, node) :
       #if less add it to left side
       if(val < node.data1) :
           if(node.l != None) :
               self._add(val, node.l)
           else :
               node.l = Node(val)
               node.l.p = node
       #if val is greater add it to right side
       else :
           if(node.r != None) :
               self._add(val, node.r)
           else :
               node.r = Node(val)
               node.r.p = node
```

```
   #In-Order-Walk
   def in_order_walk(self, node) :
       if(node != None) :
           self.in_order_walk(node.l)
           print("print node data : ", node.data1, node.data2)
           self.in_order_walk(node.r)
```

```
   #Print-root
   def print_root(self) :
       print("Data in root node", self.root.data1, self.root.data2)
```

```
   #Search the tree for wanted key
   def tree_search(self, current, key) :
       if (current == None or key == current.data1) :
           return current
       if (key < current.data1) :
           return self.tree_search(current.l, key)
       else :
           return self.tree_search(current.r, key)
```

```
   #Search the tree for wanted key iterative way
   def iterative_tree_search(self, current, key) :
       while (current != None and key != current.data1) :
           if (key  < current.data1) :
               current = current.l
           else :
               current = current.r
       return current
```

```
   #Find the tree minimum
   def tree_minimum(self, node) :
       while (node.l != None) :
           node = node.l
       return node
```

```
   #Find tree maximum
   def tree_maximum(self, node) :
       while(node.r != None) :
           node = node.r
       return node
```

```
   #Print node's parent
   def print_parrent(self, node) :
       if (node.p != None) :
           print("Parent node of node ", node.data1, "is", node.p.data1)
       else :
           print("The node ", node.data1, "is root")
```

```
   #Transplant
   def transplant(self, u, v) :
       if (u.p == None) :
           self.root = v
       elif (u == u.p.l) :
           u.p.l = v
       else :
           u.p.r = v
       if (v != None) :
           v.p = u.p   
```

```
   #Deleting node
   def delete(self, node) :
       if (node.l == None) :
           self.transplant(node, node.r)
       elif (node.r == None) :
           self.transplant(node, node.l)
       else :
           y = self.tree_minimum(node.r)
           if (y.p != z) :
               self.transplant(y, y.r)
               y.r = node.r
               y.r.p = y
           self.transplant(node, y)
           y.l = node.l
           y.l.p = y
```

```
   #In-Order-Walk-With-RetVal
   def in_order_walk_with_retval(self, node) :
       global x
       if(node != None) :
           self.in_order_walk_with_retval(node.l)
           x.append(node)
           self.in_order_walk_with_retval(node.r)
```

  

1. Testiranje

x = list()

1. Testing here

tree = Tree();
A = random\_list(0, 20, 10)
print(A)
key = A[9]
key\_i = A[6]
key\_invalid = 100

for i in range(0, len(A)) :

```
   tree.add(A[i])
```

tree.print\_root()

1. testing in order walk

tree.in\_order\_walk(tree.root)

1. testing tree search

f\_k = tree.tree\_search(tree.root, key)
if (f\_k != None) : 

```
   print("Found the key", f_k.data1, "and we searched for ", key)
```

else :

```
   print("No key", key, "found")
```

f\_k = tree.tree\_search(tree.root, key\_invalid)
if (f\_k != None) : 

```
   print("Found the key", f_k.data1, "and we searched for ", key_invalid)
```

else :

```
   print("No key", key_invalid, "found")
```

  

1. testing iterative search

f\_k\_i = tree.iterative\_tree\_search(tree.root, key\_i)
if (f\_k\_i != None) : 

```
   print("Found the key", f_k_i.data1, "and we searched for ", key_i)
```

else :

```
   print("No key", key_i, "found")
```

1. testing tree minimum

temp = tree.tree\_minimum(tree.root)
print("Tree minimum", temp.data1)

1. testing tree maximum

temp = tree.tree\_maximum(tree.root)
print("Tree minimum", temp.data1)

1. testing print parent

tree.print\_parrent(temp)
tree.print\_parrent(tree.root)

1. Testing inserting

print("Inserting 110 and -5 to tree")
tree.add(110)
tree.add(-5)
tree.in\_order\_walk(tree.root)

1. testing tree minimum

temp = tree.tree\_minimum(tree.root)
print("Tree minimum", temp.data1)

1. testing tree maximum

temp = tree.tree\_maximum(tree.root)
print("Tree minimum", temp.data1)

1. testing print parent

tree.print\_parrent(temp)

1. Trying to delete maximum

temp = tree.tree\_maximum(tree.root)
tree.delete(temp)
print("Tree after deleting max")
tree.in\_order\_walk(tree.root)

1. Trying to delete minimum

temp = tree.tree\_minimum(tree.root)
tree.delete(temp)
print("Tree after deleting min")
tree.in\_order\_walk(tree.root)

print("########")

tree.in\_order\_walk\_with\_retval(tree.root)

  

for i in x :

```
   print(i.data1)
```

Vidi još
--------

* Samobalansirajuće binarno stablo pretrage
* Binarna pretraga
* Treap
* Tango stablo
* Crveno-crno stablo
* AVL-stablo

Literatura
----------

* Šablon:DADS
* Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.; Stein, Clifford (2001). „12: Binary search trees, 15.5: Optimal binary search trees". *Introduction to Algorithms* (2nd izd.). MIT Press & McGraw-Hill. str. 253–272,356–363. ISBN 978-0-262-03293-3.
* Jarc, Duane J. (3. 12. 2005.). „Binary Tree Traversals". *Interactive Data Structure Visualizations*. University of Maryland. Arhivirano iz originala na datum 2014-02-27. Pristupljeno 2019-01-11.
* Knuth, Donald (1997). „6.2.2: Binary Tree Searching". *The Art of Computer Programming*. **3: "Sorting and Searching"** (3rd izd.). Addison-Wesley. str. 426–458. ISBN 978-0-201-89685-5.
* Long, Sean. „Binary Search Tree" (PPT). *Data Structures and Algorithms Visualization-A PowerPoint Slides Based Approach*. SUNY Oneonta.
* Parlante, Nick (2001). „Binary Trees". *CS Education Library*. Stanford University.

Spoljašnje veze
---------------

* Literate implementations of binary search trees in various languages Arhivirano 2017-04-21 na Wayback Machine-u on LiteratePrograms
* Goleta, Maksim (27. 11. 2007.). „Goletas.Collections". *goletas.com*. Arhivirano iz originala na datum 21. 04. 2014. Pristupljeno 20. 04. 2014.  Includes an iterative C# implementation of AVL trees.
* Jansens, Dana. „Persistent Binary Search Trees". Computational Geometry Lab, School of Computer Science, Carleton University.  C implementation using GLib.
* Binary Tree Visualizer (JavaScript animation of various BT-based data structures)
* Kovac, Kubo. „Binary Search Trees" (Java applet). Korešpondenčný seminár z programovania.
* Madru, Justin (18. 8. 2009.). „Binary Search Tree". *JDServer*. Arhivirano iz originala na datum 28. 03. 2010. Pristupljeno 20. 04. 2014.  C++ implementation.
* Tarreau, Willy (2011). „Elastic Binary Trees (ebtree)". *1wt.eu*.
* Binary Search Tree Example in Python
* „References to Pointers (C++)". *MSDN*. Microsoft. 2005.  Gives an example binary tree implementation.
* Igushev, Eduard. „Binary Search Tree C++ implementation". Arhivirano iz originala na datum 17. 06. 2013. Pristupljeno 20. 04. 2014.
* Stromberg, Daniel. „Python Search Tree Empirical Performance Comparison".

***Binarno stablo pretrage*** na Wikimedijinoj ostavi