Introducció
Un arbre binari de cerca (BST, per les seves sigles en anglès) és una estructura de dades que manté els elements en un ordre específic, facilitant operacions com la cerca, inserció i eliminació. En un BST, cada node té com a màxim dos fills, i es compleixen les següents propietats:
- Propietat de l'ordre: Per a qualsevol node
N:- Tots els nodes del subarbre esquerre de
Ntenen valors menors que el valor deN. - Tots els nodes del subarbre dret de
Ntenen valors majors que el valor deN.
- Tots els nodes del subarbre esquerre de
Propietats dels Arbres Binàries de Cerca
- Cerca eficient: La propietat de l'ordre permet cercar elements de manera eficient.
- Inserció i eliminació: També es poden fer de manera eficient mantenint la propietat de l'ordre.
- Recorreguts: Es poden fer recorreguts en preordre, inordre i postordre per obtenir els elements en diferents ordres.
Operacions Bàsiques
Cerca
La cerca en un BST es fa comparant el valor cercat amb el valor del node actual i decidint si es continua pel subarbre esquerre o dret.
class Node:
def __init__(self, key):
self.left = None
self.right = None
self.val = key
def search(root, key):
# Base Cases: root is null or key is present at root
if root is None or root.val == key:
return root
# Key is greater than root's key
if root.val < key:
return search(root.right, key)
# Key is smaller than root's key
return search(root.left, key)Inserció
Per inserir un nou node, es compara el valor del nou node amb els nodes existents i es col·loca en la posició correcta mantenint la propietat de l'ordre.
def insert(root, key):
# If the tree is empty, return a new node
if root is None:
return Node(key)
# Otherwise, recur down the tree
if key < root.val:
root.left = insert(root.left, key)
else:
root.right = insert(root.right, key)
# return the (unchanged) node pointer
return rootEliminació
L'eliminació d'un node en un BST és més complexa i depèn de si el node a eliminar té zero, un o dos fills.
def deleteNode(root, key):
# Base Case
if root is None:
return root
# If the key to be deleted is smaller than the root's key
if key < root.val:
root.left = deleteNode(root.left, key)
# If the key to be deleted is greater than the root's key
elif key > root.val:
root.right = deleteNode(root.right, key)
# If key is same as root's key, then this is the node to be deleted
else:
# Node with only one child or no child
if root.left is None:
temp = root.right
root = None
return temp
elif root.right is None:
temp = root.left
root = None
return temp
# Node with two children: Get the inorder successor
temp = minValueNode(root.right)
# Copy the inorder successor's content to this node
root.val = temp.val
# Delete the inorder successor
root.right = deleteNode(root.right, temp.val)
return root
def minValueNode(node):
current = node
# Loop down to find the leftmost leaf
while(current.left is not None):
current = current.left
return currentRecorreguts
Recorregut Inordre
El recorregut inordre visita els nodes en ordre ascendent.
Recorregut Preordre
El recorregut preordre visita el node actual abans de visitar els seus fills.
Recorregut Postordre
El recorregut postordre visita els fills abans de visitar el node actual.
Exercici Pràctic
Exercici 1: Implementació Bàsica
Implementa un BST en Python i realitza les operacions bàsiques de cerca, inserció i eliminació.
# Implementació completa del BST amb les operacions bàsiques
class Node:
def __init__(self, key):
self.left = None
self.right = None
self.val = key
class BST:
def __init__(self):
self.root = None
def insert(self, key):
if self.root is None:
self.root = Node(key)
else:
self._insert(self.root, key)
def _insert(self, root, key):
if key < root.val:
if root.left is None:
root.left = Node(key)
else:
self._insert(root.left, key)
else:
if root.right is None:
root.right = Node(key)
else:
self._insert(root.right, key)
def search(self, key):
return self._search(self.root, key)
def _search(self, root, key):
if root is None or root.val == key:
return root
if key < root.val:
return self._search(root.left, key)
return self._search(root.right, key)
def delete(self, key):
self.root = self._delete(self.root, key)
def _delete(self, root, key):
if root is None:
return root
if key < root.val:
root.left = self._delete(root.left, key)
elif key > root.val:
root.right = self._delete(root.right, key)
else:
if root.left is None:
return root.right
elif root.right is None:
return root.left
temp = self._minValueNode(root.right)
root.val = temp.val
root.right = self._delete(root.right, temp.val)
return root
def _minValueNode(self, node):
current = node
while current.left is not None:
current = current.left
return current
def inorder(self):
self._inorder(self.root)
def _inorder(self, root):
if root:
self._inorder(root.left)
print(root.val, end=' ')
self._inorder(root.right)
# Exemple d'ús
bst = BST()
bst.insert(50)
bst.insert(30)
bst.insert(20)
bst.insert(40)
bst.insert(70)
bst.insert(60)
bst.insert(80)
print("Inorder traversal of the given tree")
bst.inorder()
print("\n\nDelete 20")
bst.delete(20)
print("Inorder traversal of the modified tree")
bst.inorder()
print("\n\nDelete 30")
bst.delete(30)
print("Inorder traversal of the modified tree")
bst.inorder()
print("\n\nDelete 50")
bst.delete(50)
print("Inorder traversal of the modified tree")
bst.inorder()Conclusió
Els arbres binaris de cerca són una estructura de dades fonamental que permeten operacions eficients de cerca, inserció i eliminació. Comprendre com implementar i utilitzar BSTs és essencial per a qualsevol programador que treballi amb dades estructurades. En el següent mòdul, explorarem arbres AVL, una variant dels BSTs que manté l'equilibri per assegurar una eficiència òptima.
Curs d'Estructures de Dades
Mòdul 1: Introducció a les Estructures de Dades
- Què són les Estructures de Dades?
- Importància de les Estructures de Dades en la Programació
- Tipus d'Estructures de Dades
Mòdul 2: Llistes
- Introducció a les Llistes
- Llistes Enllaçades
- Llistes Doblement Enllaçades
- Llistes Circulars
- Exercicis amb Llistes
Mòdul 3: Piles
- Introducció a les Piles
- Operacions Bàsiques amb Piles
- Implementació de Piles
- Aplicacions de les Piles
- Exercicis amb Piles
Mòdul 4: Cues
- Introducció a les Cues
- Operacions Bàsiques amb Cues
- Cues Circulars
- Cues de Prioritat
- Exercicis amb Cues
Mòdul 5: Arbres
- Introducció als Arbres
- Arbres Binàries
- Arbres Binàries de Cerca
- Arbres AVL
- Arbres B
- Exercicis amb Arbres
Mòdul 6: Grafs
- Introducció als Grafs
- Representació de Grafs
- Algoritmes de Cerca en Grafs
- Algoritmes de Camins Mínims
- Aplicacions dels Grafs
- Exercicis amb Grafs
