in pseudocodice la funzione ricorsiva che avevo in mente è più o meno questa:

codice:
void Cerca(int i, int j, *cluster)
{
  SalvaIndiciNelCluster(i, j, cluster)
  SalvaIndiciProcessati(i, j);
  if (j+1 != limite_matrice) &&  CheckIndiciNonProcessati(i, j+1) && (v[i, j] == v[i, j+1])
    Cerca(i, j+1, cluster); //vado a est
  else
    if (v[i,j] == v[i+1,j]) // da qui e per i successivi controlli non riscrivo tutte le condizioni, è chiaro però che va sempre controllato sia che non siamo al limite sia che l'elemento successivo non sia gia stato considerato.
      Cerca(i+1, j, cluster); //sud
    else
      if (v[i, j] == v[i, j-1]
        Cerca(i, j-1, cluster) //ovest
      else
        if (v[i,j] == v[i-1, j])
          Cerca(i-1, j, cluster); //nord
}
il cliclo principale

codice:
InizializzaElencoIndiciProcessati;
InizializzaListaCluster;
for tutte le righe
  for tutte le colonne
    if CheckIndiciProcessati(i, j) //Considero un ipotetico cluster anche da un solo elemento solo se l'elemento in questione non è mai stato processato precedentemente
    {
       *cluster = InizializzaCluster;
       cerca(i, j, cluster)
       AggiungiAllaListaDeiCluster(cluster);
    }
alla fine ti ritroveresti una lista di liste ognuna delle quali rappresenta un cluster.