Trouver si 2 BST représentée par des tableaux sont isomorphes ou non

voix
0

1) Compte tenu de 2 tableaux contenant des éléments d'un arbre binaire complet (niveau par niveau), sans reconstruire en fait un arbre (par exemple en ne faisant des swaps dans un tableau), comment puis-je trouver si ces 2 tableaux sont isomorphes ou non?

2) Une meilleure solution si un arbre isomorphe forme binaire un arbre de recherche.

mise à jour , par exemple

     5 
    / \
    4  7
   /\  /\
  2  3 6 8

peut être représenté en tant que matrice 5 4 7 2 3 6 8

arbres isomorphes sont des arbres qui peuvent être convertis en un autre par rotation autour de noeuds

     5 
    / \
    4  7
   /\  /\
  2  3 6 8



     5 
    / \
    4  7
   /\  /\
  3  2 6 8



     5 
    / \
    4  7
   /\  /\
  3  2 8 6



     5 
    / \
    7  4
   /\  /\
  8  6 3 2
Créé 07/11/2011 à 19:30
source utilisateur
Dans d'autres langues...                            


4 réponses

voix
2

Vous pouvez faire un arbre dans l'ordre de marche sur les deux simultanément et vérifier si les éléments sont les mêmes.

Créé 07/11/2011 à 20:24
source utilisateur

voix
0

Prenant partie (2) en premier lieu, les paires de noeuds mobiles - et leurs descendants - à chaque niveau, si nécessaire pour activer chaque arbre dans un arbre de recherche binaire, avec des noeuds gauche <= noeuds droite. Cela prendra du temps n log n. Une fois que vous avez fait cela, si vous aviez un arbre de recherche binaire et un isomorphe d'arbre avec un arbre de recherche binaire, vous avez maintenant deux arbres binaires de recherche. Comme l'a souligné yi_H, cela signifie qu'un montrera les mêmes éléments dans le même ordre si les deux arbres sont isomorphes en ordre de marche des arbres. Mais un arbre en ordre de marche, dans un arbre stocké dans un tableau comme dans vos exemples, est juste une façon particulière de visiter tous les éléments du tableau, donc si les arbres sont isomorphes les deux tableaux doivent être identiques.

La meilleure façon de traiter une partie (1) est de savoir si vous pouvez trouver de l'espace supplémentaire. Pour le niveau le plus bas de chaque arbre, construire une table de hachage pour chaque arbre contenant les feuilles. Comparez les deux tables de hachage et de sortie si elles ne tiennent pas le même ensemble de nœuds. Donner à chaque feuille un identifiant qui identifie, où les identifiants sont les mêmes si les feuilles sont les mêmes. Pour les parents de ces feuilles, construire une autre table de hachage, en utilisant les valeurs de chaque parent et les identifiants de ces enfants. Encore une fois, vérifiez que les deux jeux sont les mêmes et la sortie sinon. Attribuer à chaque parent un identifiant qui est le même si la valeur au niveau du noeud est la même et les identifiants de ses enfants sont les mêmes. Vous pouvez continuer de cette façon l'arbre jusqu'à la racine. Si tous les jeux sont les mêmes tout le chemin, vous avez deux arbres isomorphes, et les identifiants vous donnent la correspondance à chaque niveau. Ceci est plus complexe que la partie (1) et prend l'espace supplémentaire, mais seulement le temps linéaire.

Créé 08/11/2011 à 06:26
source utilisateur

voix
2

Pour le premier problème:

Un peu de notation:

  • t0, t1 - Arbres
  • La valeur (t) - le numéro stocké au niveau du noeud
  • gauche (t) - le sous-arbre gauche
  • droit (t) - le sous-arbre droit

t1et t2sont isomorphes, IFF t1et t2sont vides,

ou value (t1) == value (t2)

et

soit left(t1)est isomorphe left(t2)et right(t1)est isomorphe right(t2),

ou left(t1)est isomorphe à right(t2)et right(t1)est isomorphe àleft(t2)

En supposant que les arbres sont stockés dans un des tableaux, de telle sorte que l' élément 0 est la racine et si test un indice d'un noeud interne 2t+1et 2t+2sont des indices de ses enfants immédiats, la mise en œuvre simple:

#include <stdio.h>

#define N 7

int a[] = { 5, 4, 7, 2, 3, 6, 8 };
int b[] = { 5, 7, 4, 6, 8, 2, 3 };

int
is_isomorphic (int t1, int t2)
{
  if (t1 >= N && t2 >= N)
    return 1;

  if (a [t1] != b [t2])
    return 0;

  return ((is_isomorphic (2*t1 + 1, 2*t2 + 1)
           && is_isomorphic (2*t1 + 2, 2*t2 + 2))
          || (is_isomorphic (2*t1 + 1, 2*t2 + 2)
              && is_isomorphic (2*t1 + 2, 2*t2 + 1)));
}

int main ()
{
  printf ("%s\n", (is_isomorphic (0, 0) ? "yes" : "no"));
  return 0;
}

Pour le deuxième problème, à chaque étape, on compare la sous - arborescence de ala plus petite racine à la sous - arborescence de bla plus petite racine, puis la sous - arborescence de ala plus grande racine à la sous - arborescence de bla plus grande racine (plus petit et plus grand que le courant racines de aet b).

int
is_isomorphic_bst (int t1, int t2)
{
  if (t1 >= N && t2 >= N)
    return 1;

  if (a [t1] != b [t2])
    return 0;

  int t1l, t1r, t2l, t2r;
  if (a [2*t1 + 1] < a [t1] && a [t1] < a [2*t1 + 2])
    {
      t1l = 2*t1 + 1;
      t1r = 2*t1 + 2;
    }
  else if (a [2*t1 + 1] > a [t1] && a [t1] > a [2*t1 + 2])
    {
      t1l = 2*t1 + 2;
      t1r = 2*t1 + 1;
    }
  else
    return 0;

  if (b [2*t2 + 1] < b [t2] && b [t2] < b [2*t2 + 2])
    {
      t2l = 2*t2 + 1;
      t2r = 2*t2 + 2;
    }
  else if (b [2*t2 + 1] > b [t2] && b [t2] > b [2*t2 + 2])
    {
      t2l = 2*t2 + 2;
      t2r = 2*t2 + 1;
    }
  else
    return 0;

  return is_isomorphic_bst (t1l, t2l) && is_isomorphic_bst (t1r, t2r);
}
Créé 08/11/2011 à 15:41
source utilisateur

voix
0

Pour BST:

  1. Prenez les premiers éléments des deux tableaux et correspondance. Sinon égale alors BST ne sont pas être identiques.
  2. Trouvez les premiers enfants gauche qui n'a pas été numérisés (aux positions leftPos1 et leftPos2) et correspondance. Sinon appariés alors BST ne sont pas identiques.
  3. Trouvez les premiers enfants de droite qui n'a pas été numérisés (aux positions rightPos1 et rightPos2) et correspondance. Sinon appariés alors BST ne sont pas identiques.
  4. Si les deux à gauche et à droite les enfants correspondent, l'effectuer les mêmes opérations récursive sur les deux paires de sous-listes / sous-arbre (de leftPos1 et leftPos2) et (de rightPos1 et rightPos2). Le parent de ces sous-arbre est le premier élément du tableau.

Tout en recherchant les enfants gauche et à droite dans la sous-liste, il peut y avoir des éléments qui sont déjà scannés. Pour en savoir ces éléments, vérifier cet élément qu'il peut être les enfants de la sous-arborescence actuelle. Si la sous-arborescence actuelle est à gauche du parent, puis de comparer l'élément avec le parent, si elle appartient à la droite puis ignorer cet élément.

#include <stdio.h>

#define BOOL int
#define TRUE 1
#define FALSE 0

BOOL isLeft(int parent, int child) {
    return child <= parent;
}

BOOL isRight(int parent, int child) {
    return child > parent;
}

BOOL isBelongToChild(int parent, int child, int value) {
    if (isLeft(parent, child) && (isLeft(parent, value))) {
        return TRUE;
    }
    if (isRight(parent, child) && (isRight(parent, value))) {
        return TRUE;
    }
    return FALSE;
}

int getLeftPosition(int * array, int size, int parent, BOOL parentExists) {
    int i;

    int first = *array;
    for (i = 1; i < size; i++) {
        int value = *(array + i);
        if (! isBelongToChild(parent, first, value)) {
            continue;
        }
        if (isLeft(first, value)) {
            return i;
        }
    }
    return -1;
}

int getRightPosition(int * array, int size, int parent, BOOL parentExists) {
    int i;

    int first = *array;
    for (i = 1; i < size; i++) {
        int value = *(array + i);
        if (! isBelongToChild(parent, first, value)) {
            continue;
        }
        if (isRight(first, value)) {
            return i;
        }
    }
    return -1;
}

BOOL areSame(int * array1, int pos1, int * array2, int pos2) {
    if (pos1 == -1 && pos2 == -1) {
        return TRUE;
    } else if (*(array1 + pos1) == *(array2 + pos2)) {
        return TRUE;
    } else {
        return FALSE;
    }
}

BOOL isSameBst(int * array1, int size1, int * array2, int size2, int parent, BOOL parentExists) {
    if (0 == size1 && 0 == size2) {
        return TRUE;
    }
    if (*array1 != *array2) {
        return FALSE;
    }

    int leftPos1 = getLeftPosition(array1, size1, parent, parentExists);
    int leftPos2 = getLeftPosition(array2, size2, parent, parentExists);
    if (! areSame(array1, leftPos1, array2, leftPos2)) {
        return FALSE;
    }
    int rightPos1 = getRightPosition(array1, size1, parent, parentExists);
    int rightPos2 = getRightPosition(array2, size2, parent, parentExists);
    if (! areSame(array1, rightPos1, array2, rightPos2)) {
        return FALSE;
    }

    if (leftPos1 > -1) {
        int result = isSameBst((array1 + leftPos1), size1 - leftPos1, (array2 + leftPos2), size2 - leftPos2, *array1, TRUE);
        if (FALSE == result) {
            return FALSE;
        }
    }
    if (rightPos1 > -1) {
        int result = isSameBst((array1 + rightPos1), size1 - rightPos1, (array2 + rightPos2), size2 - rightPos2, *array1, TRUE);
        if (FALSE == result) {
            return FALSE;
        }
    }
    return TRUE;
}

int main ()
{
    int a[] = { 5, 6, 2, 7, 4 };
    int b[] = { 5, 6, 7, 2, 4 };
    printf ("%s\n", (isSameBst(a, 5, b, 5, 0, FALSE) ? "yes" : "no"));
    return 0;
}
Créé 16/03/2013 à 18:30
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more