Găsirea dacă 2 BST reprezentat de matrice sunt izomorfe sau nu

voturi
0

1) Având în vedere 2 matrici care conțin elemente ale unui arbore binar complet (nivel de nivel), fără a reconstrui de fapt un copac (de exemplu, prin swap-uri fac doar într-o matrice), cum pot afla dacă aceste 2 matrice sunt izomorfe sau nu?

2) O soluție mai bună în cazul în care un copac izomorf formează un binar de căutare copac.

actualizare de exemplu ,

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

pot fi reprezentate în matrice ca 5 4 7 2 3 6 8

copaci izomorfe sunt copaci care pot fi transformate una de alta prin rotație despre noduri

     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
Întrebat 07/11/2011 la 19:30
sursa de către utilizator
În alte limbi...                            


4 răspunsuri

voturi
2

Ai putea face o plimbare copac în ordine pe ambele simultan și să verifice dacă elementele sunt aceleași.

Publicat 07/11/2011 la 20:24
sursa de către utilizator

voturi
0

A lua parte (2) prima, perechile de swap de noduri - și descendenții acestora - la fiecare nivel, după cum este necesar pentru a transforma fiecare copac într-un arbore binar de căutare, cu noduri din stânga <= noduri dreapta. Acest lucru va avea nevoie de timp n log. După ce ați făcut acest lucru, dacă ați avea un arbore binar de căutare și un copac izomorf cu un arbore binar de căutare, aveți acum doi arbori de căutare binare. După cum a subliniat yi_H, acest lucru înseamnă că o plimbare copac în ordine va arăta aceleași elemente în aceeași ordine în cazul în care ambii arbori sunt izomorfe. Dar o plimbare copac în ordine, într-un copac stocate într-o matrice ca în exemplele tale, este doar un mod aparte de a vizita toate elementele de matrice, astfel încât în ​​cazul în care copacii sunt izomorfe cele două matrice trebuie să fie identice.

Cel mai simplu mod de a gestiona o parte (1), este dacă puteți găsi un spațiu suplimentar. Pentru cel mai scăzut nivel al fiecărui copac, să construiască un tabel hash pentru fiecare copac exploatație frunze. Comparați cele două tabele de dispersie și de ieșire în cazul în care nu dețin același set de noduri. Dă fiecare frunză un identificator care identifică, în cazul în care identificatorii sunt aceleași în cazul în care frunzele sunt aceleași. Pentru părinții acestor frunze, a construi un alt tabel hash, folosind valorile de la fiecare părinte și identificatorii acelor copii. Din nou, verificați dacă cele două seturi sunt aceleași și ieșire în cazul în care nu. Atribuie fiecărui părinte un identificator care este același în cazul în care valoarea de la nodul este aceeași și identificatorii copiilor săi sunt aceleași. Puteți continua în acest fel până copac, până când ajunge la rădăcină. În cazul în care toate seturile sunt aceleași tot drumul în sus, aveți doi copaci izomorfe, iar identificatorii da corespondența la fiecare nivel. Acest lucru este mult mai complexă decât o parte (1) și are spațiu suplimentar, dar numai timpul liniar.

Publicat 08/11/2011 la 06:26
sursa de către utilizator

voturi
2

Pentru prima problemă:

Un pic de notație:

  • t0, t1 - copaci
  • valoarea (t) - numărul stocat la nodul
  • stânga (t) - subarborele stâng
  • dreapta (t) - subarborele dreapta

t1și t2sunt izomorfe, IFF t1și t2sunt goale,

sau value (t1) == value (t2)

și

fie left(t1)este izomorfă left(t2)și right(t1)este izomorfă right(t2),

sau left(t1)este izomorfă right(t2)și right(t1)este izomorfăleft(t2)

Presupunând că arborii sunt stocate într - o matrice, astfel încât elementul 0 este rădăcina și și dacă teste un indice al unui nod intern 2t+1și 2t+2sunt indicii ale copiilor săi imediate, punerea în aplicare simplă:

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

Pentru a doua problemă, la fiecare pas, vom compara subarborele a acu rădăcină mai mică la subarborele a brădăcinii mai mici și apoi subarborele a acu rădăcină mai mare la subarborele a brădăcinii mai mare (mai mică și mai mare decât curentul rădăcinile ași 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);
}
Publicat 08/11/2011 la 15:41
sursa de către utilizator

voturi
0

Pentru BST:

  1. Ia primele elemente ale ambelor tablouri și potrivire. În cazul în care nu este egal, atunci BST nu sunt fie aceleași.
  2. Găsiți primii copii rămași , care nu a fost scanată (la pozițiile leftPos1 și leftPos2) și meciul. În cazul în care nu se potrivesc , atunci BST nu sunt aceleași.
  3. Găsiți primii copii dreapta care nu a fost scanate (la pozițiile rightPos1 și rightPos2) și meciul. În cazul în care nu se potrivesc , atunci BST nu sunt aceleași.
  4. În cazul în care se potrivesc atât cu copii stânga și dreapta, efectuați aceleași operații recursiv pe cele două perechi de subliste / subarborelui (de la leftPos1 și leftPos2) și (de la rightPos1 și rightPos2). Părintele acestor subramificație este primul element al șirului.

În timp ce caută copiii stânga și dreapta în sublista, pot exista elemente care sunt deja scanate. Pentru a afla astfel de elemente, verificați dacă acel element care poate fi copiii subarborelui curent. În cazul în care subarborele curent este la partea stanga a părintelui, apoi comparați elementul cu părintele, în cazul în care fac parte din partea dreaptă, apoi ignora acel element.

#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;
}
Publicat 16/03/2013 la 18:30
sursa de către utilizator

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