Het onderzoek of 2 BST vertegenwoordigers reeksen isomorf indien

stemmen
0

1) Aangezien 2 arrays die elementen bevatten van een volledige binaire boom (per niveau), zonder dat het reconstrueren van een boom (dat wil zeggen door het doen van alleen swaps in een array), hoe kan ik vinden of deze 2 reeksen isomorf zijn of niet?

2) Een betere oplossing als men isomorf boom vormt een Binary Search Tree.

updaten bv

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

kan worden weergegeven in array 5 4 7 2 3 6 8

Isomorf bomen zijn bomen die kunnen worden omgezet met elkaar door rotatie om knooppunten

     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
De vraag is gesteld op 07/11/2011 om 19:30
bron van user
In andere talen...                            


4 antwoorden

stemmen
2

Je zou een in-order boom gang te doen op hen beiden tegelijk en controleer of de elementen zijn hetzelfde.

antwoordde op 07/11/2011 om 20:24
bron van user

stemmen
0

Deelnemers (2) eerste, swap paren knooppunten - en hun nakomelingen - op elk niveau, dit tot alle boom zetten in een binaire zoekboom, met links nodes <= rechts nodes. Dit zal enige tijd duren n log n. Zodra je dit hebt gedaan, als je een binary search boom en een boom isomorf met een binaire zoekboom, je hebt nu twee binaire zoekboom. Zoals opgemerkt door yi_H, betekent dit dat een in-order boom lopen dezelfde elementen in dezelfde volgorde zal uitwijzen of beide bomen zijn isomorf. Maar een in-orde boom gang, in een boom opgeslagen in een array als in uw voorbeeld, is slechts een eigenaardige manier van het bezoeken van alle elementen van de array, dus als de bomen zijn isomorf de twee arrays moeten identiek zijn.

De eenvoudigste manier om deel te behandelen (1) is als u extra ruimte kan vinden. Voor het laagste niveau van elke boom, het bouwen van een hash-tabel voor elke boom die de bladeren. Vergelijk de twee hash tabellen en uitstappen als ze niet dezelfde set van knooppunten houden. Geef elk blad een identificatie die het identificeert, waarbij de identifiers zijn hetzelfde als de bladeren zijn hetzelfde. Voor de ouders van die bladeren, het bouwen van een andere hash tafel, met behulp van de waarden bij elke ouder en de identifiers van die kinderen. Nogmaals, controleer dan of de twee groepen zijn hetzelfde en exit, zo niet. Wijs elke ouder een identificator die hetzelfde als de waarde bij de knoop is hetzelfde en de identificaties van de kinderen zijn gelijk. U kunt doorgaan op deze manier de boom tot aan de wortel te bereiken. Als alle sets zijn gelijk helemaal naar boven, heb je twee isomorfe bomen, en de identifiers geven u de correspondentie op elk niveau. Dit is ingewikkelder dan (1) en neemt extra ruimte, maar alleen lineaire tijd.

antwoordde op 08/11/2011 om 06:26
bron van user

stemmen
2

Voor het eerste probleem:

Een beetje notatie:

  • t0, t1 - bomen
  • waarde (t) - het aantal opgeslagen bij knooppunt
  • links (t) - de linker deelboom
  • rechts (t) - de rechter deelboom

t1en t2zijn isomorf, IFF t1en t2leeg zijn,

of value (t1) == value (t2)

en

ofwel left(t1)isomorf is left(t2)en right(t1)isomorf is right(t2),

of left(t1)isomorf is right(t2)en right(t1)is isomorf metleft(t2)

Ervan uitgaande dat de bomen worden opgeslagen in een array, zodat element 0 is en de wortel en als teen index van de interne knoop 2t+1en 2t+2indices zijn van de onmiddellijke kinderen, eenvoudige uitvoering:

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

Voor het tweede probleem, bij elke stap, vergelijken we de substructuur van ade kleinere wortel naar de substructuur van bde kleinere wortel en de subboom van ade grotere wortel naar de substructuur van bde grotere root (kleiner en groter dan de huidige wortels van aen 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);
}
antwoordde op 08/11/2011 om 15:41
bron van user

stemmen
0

Voor BST:

  1. Neem de eerste elementen van beide arrays en match. Indien niet gelijk vervolgens BST niet hetzelfde zijn.
  2. Vind de eerste straat links kinderen die nog niet is gescand (op de posities leftPos1 en leftPos2) en matchen. Zo niet dan geëvenaard BST zijn niet hetzelfde.
  3. Vind de eerste straat rechts kinderen die nog niet is gescand (op de posities rightPos1 en rightPos2) en matchen. Zo niet dan geëvenaard BST zijn niet hetzelfde.
  4. Indien links en rechts kinderen passen, het uitvoeren van dezelfde bewerkingen recursief aan beide paar sublijsten / deelboom (van leftPos1 en leftPos2) en (uit rightPos1 en rightPos2). De ouder van deze substructuur is het eerste element van de array.

Tijdens het zoeken links en rechts kinderen in de sublijst, kunnen er elementen die al zijn gescand. Dergelijke elementen informatie, controleert element dat u de kinderen van de huidige subboom. Als de huidige subboom is links van de ouder, vergelijk het element met de ouder, als deze behoort tot de rechterkant dan negeren 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;
}
antwoordde op 16/03/2013 om 18:30
bron van user

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