Finne om to BST representert av arrays er isomorfe eller ikke

stemmer
0

1) Gitt 2 matriser som inneholder elementer av et komplett binært tre (nivå for nivå), uten egentlig å rekonstruere et tre (dvs. ved å bare gjøre bytteavtaler i en rekke), hvordan kan jeg finne ut om de 2 arrays er isomorfe eller ikke?

2) En bedre løsning hvis en isomorphic tre danner et binært søketre.

oppdatering f.eks

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

kan være representert i matrisen som 5 4 7 2 3 6 8

Isomorfe trær er trær som kan konverteres til hverandre ved rotasjon om nodene

     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
Publisert på 07/11/2011 klokken 18:30
kilden bruker
På andre språk...                            


4 svar

stemmer
2

Du kan gjøre en in-order tre gange på begge av dem samtidig og sjekke om elementene er de samme.

Svarte 07/11/2011 kl. 19:24
kilden bruker

stemmer
0

Tar del (2) første, bytte par av noder - og deres etterkommere - på hvert nivå, som er nødvendig for å vende hvert tre i et binært søk tre, med venstre noder <= riktige noder. Dette vil ta tid n log n. Når du har gjort dette, hvis du hadde et binært søketre og et tre isomorphic med et binært søketre, har du nå to binære søketrær. Som påpekt av yi_H, betyr dette at en i for tre gange vil vise de samme elementene i samme rekkefølge dersom begge trær er isomorfe. Men en in-order treet tur, i et tre som er lagret i en matrise som i dine eksempler, er bare en særegen måte å besøke alle elementene i matrisen, så hvis trærne er isomorfe de to matrisene må være identiske.

Den enkleste måten å håndtere en del (1) er om du kan finne mer plass. For det laveste nivået på hvert tre, bygge en hash tabell for hvert tre som holder bladene. Sammenligne de to hash tabeller og avslutte hvis de ikke holder samme sett av noder. Gi hvert blad en identifikator som identifiserer det, hvor identifikatorer er de samme dersom bladene er de samme. For foreldrene til disse bladene, bygge en annen hash table, ved hjelp av verdiene på hver av foreldrene og identifikatorer av disse barn. Igjen, sjekk at de to settene er de samme og avslutte hvis ikke. Tildel hver forelder en identifikator som er den samme hvis verdien ved knutepunktet er den samme og identifikatorene for sine barn er de samme. Du kan fortsette på denne måten opp i treet til du kommer til roten. Hvis alle settene er de samme hele veien opp, har du to isomorphic trær, og identifikatorer gi deg korrespondanse på hvert nivå. Dette er mer kompleks enn en del (1) og tar ekstra plass, men bare lineær tid.

Svarte 08/11/2011 kl. 05:26
kilden bruker

stemmer
2

For det første problemet:

En bit av notasjon:

  • t0, t1 - trær
  • verdi (t) - tallet som er lagret ved knutepunkt
  • venstre (t) - venstre treet
  • høyre (t) - høyre subtre

t1og t2er isomorfe, iff t1og t2er tomme,

eller value (t1) == value (t2)

og

enten left(t1)er isomorf med left(t2)og right(t1)er isomorf med right(t2),

eller left(t1)er isomorf med right(t2)og right(t1)er isomorf medleft(t2)

Antas det at trærne er lagret i en matriser, slik at elementet er 0 roten og og hvis ter en indeks av en innvendig node 2t+1og 2t+2er indeksene for dens umiddelbare barn, enkel gjennomføring:

#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;
}

For det andre problemet, ved hvert trinn, sammenligner vi undertreet til amed det mindre rot til undertreet til bmed det mindre rot og deretter undertreet til amed større rot til undertreet til bmed større rot (mindre og større enn den nåværende røtter aog 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);
}
Svarte 08/11/2011 kl. 14:41
kilden bruker

stemmer
0

For BST:

  1. Ta de første elementer av både arrays og kamp. Hvis ikke lik så BST ikke være det samme.
  2. Finn første til venstre barn som ikke har blitt skannet (på stillingene leftPos1 og leftPos2) og kamp. Hvis ikke matchet så BST er ikke samme.
  3. Finn første til høyre barn som ikke har blitt skannet (på stillingene rightPos1 og rightPos2) og kamp. Hvis ikke matchet så BST er ikke samme.
  4. Hvis både venstre og høyre barn matche, den utføre de samme operasjonene rekursivt på to par underlister / undertreet (fra leftPos1 og leftPos2) og (fra rightPos1 og rightPos2). Den overordnede av disse subtre er det første element i matrisen.

Mens du søker på venstre og høyre barn i underliste, kan det være elementer som allerede er skannet. For å finne ut slike elementer, verifisere at elementet som det kan være barn av den aktuelle undertreet. Hvis gjeldende treet er på venstre side av den overordnede, og deretter sammenligne elementet med den overordnede, hvis det tilhører høyresiden, deretter ignorere det elementet.

#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;
}
Svarte 16/03/2013 kl. 17:30
kilden bruker

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