Βρίσκοντας το αν 2 BST εκπροσωπείται από συστοιχίες είναι ισομορφικοί ή όχι

ψήφοι
0

1) Δεδομένου 2 συστοιχίες που περιέχει στοιχεία από ένα πλήρες δυαδικό δέντρο (επίπεδο από το επίπεδο), χωρίς στην πραγματικότητα ανακατασκευή ένα δέντρο (δηλαδή μόνο κάνει swaps σε μια σειρά), πώς μπορώ να βρω αν οι 2 σειρές είναι ισομορφικοί ή όχι;

2) Μια καλύτερη λύση αν ισομορφικός δέντρο σχηματίζει ένα δυαδικό Αναζήτηση δέντρο.

ενημέρωση π.χ.

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

μπορεί να αναπαρασταθεί στην διάταξη ως 5 4 7 2 3 6 8

Ισομορφικός δέντρα είναι τα δέντρα τα οποία μπορεί να μετατραπεί σε ένα άλλο με περιστροφή γύρω από τους κόμβους

     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
Δημοσιεύθηκε 07/11/2011 στις 19:30
πηγή χρήστη
Σε άλλες γλώσσες...                            


4 απαντήσεις

ψήφοι
2

Θα μπορούσατε να κάνετε μια σε σειρά πόδια δέντρο και τα δύο ταυτόχρονα και να ελέγξει αν τα στοιχεία είναι τα ίδια.

Απαντήθηκε 07/11/2011 στις 20:24
πηγή χρήστη

ψήφοι
0

Λαμβάνοντας μέρος (2) πρώτα, ζευγάρια ανταλλαγής των κόμβων - και οι απόγονοί τους - σε κάθε επίπεδο, όπως είναι απαραίτητο για να μετατρέψει κάθε δέντρο σε ένα δυαδικό δένδρο αναζήτησης, με το αριστερό κόμβους <= δεξιά κόμβους. Αυτό θα πάρει χρόνο n log n. Αφού έχετε κάνει αυτό, αν είχατε ένα δυαδικό δέντρο αναζήτησης και ισομορφικός δέντρο με ένα δυαδικό δέντρο αναζήτησης, τώρα έχετε δύο δυαδικά δέντρα αναζήτησης. Όπως επισημαίνεται από yi_H, αυτό σημαίνει ότι μια σε σειρά πόδια δέντρο θα δείξει τα ίδια στοιχεία με την ίδια σειρά, αν και τα δύο δέντρα είναι ισομορφικοί. Αλλά μια σε σειρά πόδια δέντρο, σε ένα δέντρο αποθηκεύονται σε μια σειρά όπως στα παραδείγματα σας, είναι απλά ένα περίεργο τρόπο να επισκεφθείτε όλα τα στοιχεία του πίνακα, οπότε αν τα δέντρα είναι ισομορφικοί οι δύο πίνακες πρέπει να είναι πανομοιότυπα.

Ο ευκολότερος τρόπος για να χειριστεί μέρος (1) είναι αν μπορείτε να βρείτε επιπλέον χώρο. Για το χαμηλότερο επίπεδο του κάθε δέντρου, την κατασκευή ενός πίνακα κατακερματισμού για κάθε δέντρο που κατέχουν τα φύλλα. Συγκρίνετε τις δύο πίνακες κατακερματισμού και την έξοδο, αν δεν κατέχουν το ίδιο σύνολο των κόμβων. Δώστε σε κάθε φύλλο ένα αναγνωριστικό που προσδιορίζει, όπου τα αναγνωριστικά είναι το ίδιο αν τα φύλλα είναι τα ίδια. Για τους γονείς αυτών των φύλλων, να χτίσουν ένα άλλο πίνακα κατακερματισμού, χρησιμοποιώντας τις τιμές σε κάθε γονέα και τα αναγνωριστικά των παιδιών αυτών. Και πάλι, βεβαιωθείτε ότι οι δύο ομάδες είναι το ίδιο και εξόδου, αν όχι. Αντιστοιχίστε κάθε γονέα ένα αναγνωριστικό που είναι το ίδιο, αν η τιμή στον κόμβο είναι το ίδιο και τα αναγνωριστικά των παιδιών του είναι το ίδιο. Μπορείτε να συνεχίσουμε σε αυτό το δρόμο μέχρι το δέντρο μέχρι να φτάσετε στη ρίζα. Αν όλες οι ομάδες είναι ίδιες σε όλη τη διαδρομή μέχρι, έχετε δύο ισομορφικό δέντρα και τα αναγνωριστικά σας δώσει την αντιστοιχία σε κάθε επίπεδο. Αυτό είναι πιο πολύπλοκη από μέρος (1) και λαμβάνει επιπλέον χώρο, αλλά μόνο γραμμικό χρόνο.

Απαντήθηκε 08/11/2011 στις 06:26
πηγή χρήστη

ψήφοι
2

Για το πρώτο πρόβλημα:

Ένα κομμάτι της σημειογραφίας:

  • t0, t1 - δέντρα
  • τιμή (t) - ο αριθμός που είναι αποθηκευμένος στον κόμβο
  • αριστερά (t) - το αριστερό υποδένδρο
  • δεξιά (t) - το δικαίωμα υποδένδρο

t1και t2είναι ισόμορφη, αν και μόνο αν t1και t2είναι άδειο,

ή value (t1) == value (t2)

και

είτε left(t1)είναι ισόμορφη με left(t2)και right(t1)είναι ισόμορφη με right(t2),

ή left(t1)είναι ισόμορφη με right(t2)και right(t1)είναι ισόμορφη μεleft(t2)

Υποθέτοντας ότι τα δέντρα είναι αποθηκευμένα σε ένα συστοιχίες, έτσι ώστε το στοιχείο 0 είναι η ρίζα και και αν tείναι ένας δείκτης έναν εσωτερικό κόμβο 2t+1και 2t+2είναι δείκτες της άμεσης παιδιά της, απλή εφαρμογή:

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

Για το δεύτερο πρόβλημα, σε κάθε βήμα, συγκρίνουμε την υποδένδρο του aμε τη μικρότερη ρίζα προς το υποδένδρο του bμε το μικρότερο ρίζας και στη συνέχεια το υποδένδρο του aμε την μεγαλύτερη ρίζα προς το υποδένδρο του bμε την μεγαλύτερη ρίζα (μικρότερο και μεγαλύτερο από την τρέχουσα ρίζες aκαι 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);
}
Απαντήθηκε 08/11/2011 στις 15:41
πηγή χρήστη

ψήφοι
0

Για BST:

  1. Πάρτε τα πρώτα στοιχεία των δύο πινάκων και αγώνα. Εάν δεν είναι ίσες τότε BST δεν είναι ίδια.
  2. Βρείτε τα πρώτα άφησε τα παιδιά που δεν έχουν σαρωθεί (στις θέσεις leftPos1 και leftPos2) και αγώνα. Αν δεν ταιριάζουν τότε BST δεν είναι ίδια.
  3. Βρείτε τις πρώτες δικαίωμα των παιδιών που δεν έχει σαρωθεί (στις θέσεις rightPos1 και rightPos2) και αγώνα. Αν δεν ταιριάζουν τότε BST δεν είναι ίδια.
  4. Αν ταιριάζει με τα δύο αριστερά και δεξιά τα παιδιά, το εκτελεί τις ίδιες λειτουργίες αναδρομικά για τα δύο ζεύγη των υποκαταλόγους / υποδένδρο (από leftPos1 και leftPos2) και (από rightPos1 και rightPos2). Ο γονέας αυτών υποδένδρου είναι το πρώτο στοιχείο του πίνακα.

Ψάχνοντας το αριστερό και το δικαίωμα των παιδιών στην δευτερεύουσα, μπορεί να υπάρχουν στοιχεία που έχουν ήδη σαρωθεί. Για να μάθετε τα στοιχεία αυτά, βεβαιωθείτε ότι το στοιχείο που μπορεί να είναι τα παιδιά της τρέχουσας υποδένδρο. Εάν η τρέχουσα υποδένδρο είναι σε αριστερή πλευρά του γονέα, τότε συγκρίνουμε το στοιχείο με τη μητρική, αν ανήκουν στην δεξιά πλευρά, στη συνέχεια, να αγνοήσει το στοιχείο αυτό.

#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;
}
Απαντήθηκε 16/03/2013 στις 18:30
πηγή χρήστη

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