Corso IN110 Algoritmi e Strutture Dati

Gli esercizi

Testi e soluzioni di alcuni esercizi

Alberi binari di ricerca

/*
**  alberiBinariDiRicerca.c
**
**  Implementazione della struttura dati di Albero Binario di Ricerca
**  e degli algoritmi per operare sull'albero:
**   - inserimento di un elemento
**   - ricerca di un elemento
**   - calcolo del predecessore e del successore di un elemento
**   - calcolo del minimo
**   - calcolo del massimo
**   - ordinamento dell'albero
*/

#include <stdlib.h>
#include <stdio.h>

struct nodo {
  int info;
  struct nodo *padre, *sx, *dx;
};

/*
 *  inserisci(r, x)
 *
 *  inserisce un nuovo nodo con valore v nell'albero binario
 *  di ricerca con radice in r.
 */

struct nodo *inserisci(struct nodo *r, int v) {
  struct nodo *x, *y=NULL, *p;

  x = r;
  while (x != NULL) {
    y = x;
    if (x->info > v)
      x = x->sx;
    else
      x = x->dx;
  }

  p = malloc(sizeof(struct nodo));
  p->info  = v;
  p->sx    = NULL;
  p->dx    = NULL;
  p->padre = y;

  if (y == NULL) {
    r = p;
  } else {
    if (y->info > v)
      y->sx = p;
    else
      y->dx = p;
  }
  return r;
}

/*
 *  search(r, x)
 *
 *  cerca l'elemento con valore x nell'albero con radice in r.
 *  Se lo trova restituisce il puntatore a quell'elemento, 
 *  altrimenti restituisce NULL.
 */

struct nodo *search(struct nodo *r, int x) {
  struct nodo *p;
  p = r;
  while (p != NULL && p->info != x) {
    if (p->info > x)
      p = p->sx;
    else
      p = p->dx;
  }
  return p;
}

/*
 *  min(p)
 *
 *  restituisce il puntatore all'elemento di valore minimo 
 *  presente nel sottoalbero con radice in p.
 */

struct nodo *min(struct nodo *p) {
  while (p->sx != NULL)
    p = p->sx;
  return p;
}

/*
 *  max(p)
 *
 *  restituisce il puntatore all'elemento di valore massimo
 *  presente nel sottoalbero con radice in p.
 */

struct nodo *max(struct nodo *p) {
  while (p->dx != NULL)
    p = p->dx;
  return p;
}

/*
 *  predecessore(p)
 *  
 *  restituisce, se esiste, il puntatore all'elemento che
 *  precede p->info nell'ordine crescente degli elementi
 *  presenti nell'albero.
 */

struct nodo *predecessore(struct nodo *p) {
  struct nodo *q;
  if (p->sx != NULL) {
    q = max(p->sx);
  } else {
    while (p->padre != NULL && p != p->padre->dx)
      p = p->padre;
    q = p->padre;
  }
  return q;
}

/*
 *  successore(p)
 *  
 *  restituisce, se esiste, il puntatore all'elemento che
 *  segue p->info nell'ordine crescente degli elementi
 *  presenti nell'albero.
 */

struct nodo *successore(struct nodo *p) {
  struct nodo *q;
  if (p->dx != NULL) {
    q = min(p->dx);
  } else {
    while (p->padre != NULL && p != p->padre->sx)
      p = p->padre;
    q = p->padre;
  }
  return q;
}

/*
 *  sort(p)
 *
 *  visualizza in output in ordine crescente il valore dei
 *  vertici nel sottoalbero con radice in p.
 */

void sort(struct nodo *p) {
  if (p != NULL) {
    sort(p->sx);
    printf("%d ", p->info);
    sort(p->dx);
  }
  return;
}

/*
 *  Funzione principale
 */

int main(void) {
  struct nodo *r = NULL, *p, *q;
  int i, n, x;
  printf("Numero di elementi da inserire nell'albero: ");
  scanf("%d", &n);
  printf("Inserisci %d numeri interi: ", n);
  for (i=0; i<n; i++) {
    scanf("%d", &x);
    r = inserisci(r, x);
  }
  printf("Elemento da cercare nell'albero: ");
  scanf("%d", &x);
  p = search(r, x);
  if (p != NULL) {
    printf("L'elemento %d e' presente nell'albero.\n", x);
    if (p->padre != NULL)
      printf("Il padre di %d e' %d.\n", x, p->padre->info);
    else
      printf("%d e' la radice dell'albero.\n", x);
    if (p->sx != NULL) 
      printf("Il figlio sinistro di %d e' %d.\n", x, p->sx->info);
    if (p->dx != NULL) 
      printf("Il figlio destro di %d e' %d.\n", x, p->dx->info);
    q = predecessore(p);
    if (q != NULL) 
      printf("Il predecessore di %d e' %d.\n", x, q->info);
    else 
      printf("%d non ha un predecessore.\n", x);
    q = successore(p);
    if (q != NULL) 
      printf("Il successore di %d e' %d.\n", x, q->info);
    else 
      printf("%d non ha un successore.\n", x);
  }
  printf("L'elemento minimo dell'albero e' %d.\n", min(r)->info);
  printf("L'elemento massimo dell'albero e' %d.\n", max(r)->info);
  printf("Elementi in ordine crescente: ");
  sort(r);
  printf("\n\n");
  return 0;
}

Università degli Studi Roma Tre - Dipartimento di Matematica e Fisica - Corso di laurea in Matematica - Corso di Algoritmi e Strutture Dati (IN110)

Author: Marco Liverani - Last modified: Saturday December 13, 2025 - URI: http://www.mat.uniroma3.it/users/liverani/IN110/alberiBinariDiRicerca.shtml