Struttura dei dati - Albero di ricerca binario

Un albero di ricerca binario (BST) è un albero in cui tutti i nodi seguono le proprietà indicate di seguito:

  • Il valore della chiave del sottoalbero sinistro è inferiore al valore della chiave del suo nodo padre (radice).

  • Il valore della chiave del sottoalbero destro è maggiore o uguale al valore della chiave del suo nodo padre (radice).

Pertanto, BST divide tutti i suoi sottoalberi in due segmenti; il sottoalbero sinistro e il sottoalbero destro e può essere definito come -

left_subtree (keys) < node (key) ≤ right_subtree (keys)

Rappresentazione

BST è una raccolta di nodi disposti in modo tale da mantenere le proprietà BST. Ogni nodo ha una chiave e un valore associato. Durante la ricerca, la chiave desiderata viene confrontata con le chiavi in ​​BST e, se trovata, viene recuperato il valore associato.

Di seguito è una rappresentazione pittorica della BST -

Osserviamo che la chiave del nodo radice (27) ha tutte le chiavi di minor valore nel sottoalbero di sinistra e le chiavi di valore più alto sul sottoalbero di destra.

Operazioni di base

Di seguito sono riportate le operazioni di base di un albero:

  • Search - Cerca un elemento in un albero.

  • Insert - Inserisce un elemento in un albero.

  • Pre-order Traversal - Attraversa un albero in modalità pre-ordine.

  • In-order Traversal - Attraversa un albero in modo ordinato.

  • Post-order Traversal - Attraversa un albero in modo post-ordine.

Nodo

Definisci un nodo con alcuni dati, riferimenti ai suoi nodi figlio sinistro e destro.

struct node {
   int data;   
   struct node *leftChild;
   struct node *rightChild;
};

Operazione di ricerca

Ogni volta che si deve cercare un elemento, avviare la ricerca dal nodo radice. Quindi, se i dati sono inferiori al valore chiave, cerca l'elemento nella sottostruttura sinistra. Altrimenti, cerca l'elemento nella sottostruttura a destra. Segui lo stesso algoritmo per ogni nodo.

Algoritmo

struct node* search(int data){
   struct node *current = root;
   printf("Visiting elements: ");
	
   while(current->data != data){
	
      if(current != NULL) {
         printf("%d ",current->data);
			
         //go to left tree
         if(current->data > data){
            current = current->leftChild;
         }  //else go to right tree
         else {                
            current = current->rightChild;
         }
			
         //not found
         if(current == NULL){
            return NULL;
         }
      }			
   }
   
   return current;
}

Inserisci operazione

Ogni volta che deve essere inserito un elemento, individuare prima la sua posizione corretta. Inizia la ricerca dal nodo radice, quindi se i dati sono inferiori al valore della chiave, cerca la posizione vuota nella sottostruttura sinistra e inserisci i dati. Altrimenti, cerca la posizione vuota nella sottostruttura destra e inserisci i dati.

Algoritmo

void insert(int data) {
   struct node *tempNode = (struct node*) malloc(sizeof(struct node));
   struct node *current;
   struct node *parent;

   tempNode->data = data;
   tempNode->leftChild = NULL;
   tempNode->rightChild = NULL;

   //if tree is empty
   if(root == NULL) {
      root = tempNode;
   } else {
      current = root;
      parent = NULL;

      while(1) {                
         parent = current;
			
         //go to left of the tree
         if(data < parent->data) {
            current = current->leftChild;                
            //insert to the left
				
            if(current == NULL) {
               parent->leftChild = tempNode;
               return;
            }
         }  //go to right of the tree
         else {
            current = current->rightChild;
            
            //insert to the right
            if(current == NULL) {
               parent->rightChild = tempNode;
               return;
            }
         }
      }            
   }
}