2 δυαδικά δέντρα είναι ίσες ή όχι

ψήφοι
7

Πιθανή Διπλότυπο:
Προσδιορίστε αν τα δύο δυαδικά δέντρα είναι ίσα

Πήρε μια συνέντευξη χθες, μια ερώτηση με πήρε, εδώ είναι:

Περιγραφή

Υπάρχουν 2 binary trees, ελέγξτε αν είναι ίσες.

Αυτοί είναι ίσες αν και μόνο αν tree1->child == tree2->child, και ένα δέντρο του αριστερά και δεξιά children can be swapped with each other.

Για παράδειγμα:

    5     6
   / \   / \           they are equal.
   1 2   2  1

    5         6
   / \       / \           they are equal.
  1   2     2   1
 /     \   /    / 
3       4 4     3

Οποιεσδήποτε ιδέες εκτίμησα.

Δημοσιεύθηκε 12/10/2011 στις 01:18
πηγή χρήστη
Σε άλλες γλώσσες...                            


6 απαντήσεις

ψήφοι
9

φορείς ισότητας αποτελούν μεταβατικό: Αν Α = Β, και Β = C, τότε το Α = Β = C έτσι A = C.

φορείς Ισότητας είναι αυτοπαθής: Α = Α, Β = Β, και C = C δεν έχει σημασία ποιες είναι οι αξίες τους.

φορείς Ισότητας είναι συμμετρικές. Αν Α = Β, τότε το Β = Α. (Δεν έχει σημασία ποια σειρά θα είναι.)

Τώρα, λαμβάνοντας μια ματιά στον ορισμό που σας έδωσε:

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

Με λίγα λόγια, είναι μια μίζερη ερώτηση.

Ας δούμε τι θα συμβεί αν αποφασίσουμε θέλουμε να προσπαθήσουμε και να διαλευκάνουν το ζήτημα, όμως.

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

Και να θυμάστε ότι αυτό υποτίθεται ότι είναι μια αναζήτηση δέντρο. Ως εκ τούτου, μπορούμε να υποθέσουμε ότι κατά πάσα πιθανότητα δύο διαφορετικά δέντρα αναζήτησης που υποβάλλονται σε επεξεργασία από τον ίδιο αλγόριθμο πρέπει να δώσει το ίδιο αποτέλεσμα αν είναι ίσες. Έτσι, αν στραφούν γύρω από τα στοιχεία ενός δέντρου, τότε ο χρόνος αναζήτησης θα επηρεαστούν. Έτσι, τα δέντρα που δεν έχουν κάθε κόμβου στη θέση του δεν είναι ίσες μεταξύ τους.

Κάνοντας ότι μαζί με την «swappable» ιδιοκτησία της ισότητας, μπορούμε να δούμε ότι δεν είναι ένα έγκυρο ορισμό της ισότητας. (Αν προσπαθήσουμε να την εφαρμόσουμε, τότε αποδεικνύεται ότι μόνο τα δέντρα που έχουν τον ίδιο κόμβο για κάθε κόμβο σε ένα συγκεκριμένο επίπεδο είναι ίσες, και μόνο για τον εαυτό τους, η οποία σπάει το μέρος αναστοχασμού ενός φορέα ισότητας.)

Απαντήθηκε 12/10/2011 στις 01:24
πηγή χρήστη

ψήφοι
3

Εάν εφαρμόσετε τον ορισμό τους «ισότητας» με flip-αναλλοίωτο, θα παραβίαζε τον ορισμό της ισότητας. Ο ορισμός δεν έχει καν νόημα, γιατί αυτό δεν είναι το πώς δυαδικό δέντρο αναζήτησης είναι ίσες (εκτός αν κάθε κόμβος έχει ένα δείκτη προς το οποίο υποδέντρο είναι «μεγαλύτερο» και το οποίο είναι «λιγότερο»).

Έχετε δύο επιλογές της εύλογης ορισμοί:

  1. τοπολογική (flip-αγνωστικιστής) ισοδυναμία (στην οποία περίπτωση δεν μπορείτε να το ονομάσουμε ένα «δυαδικό δένδρο αναζήτησης» επειδή δεν είναι ταξινομημένο):

    tree1==tree2 που σημαίνει set(tree1.children)==set(tree2.children)

  2. κανονικό δέντρο αναζήτησης (flip-φροντίδα) ισοδυναμία:

    tree1==tree2 που σημαίνει list(tree1.children)==list(tree2.children)

Για δυαδικά δέντρα, οι παραπάνω ορισμοί θα λειτουργήσει ως γραμμένο σε οποιαδήποτε γλώσσα που υποστηρίζει η listκαι setτύπους δεδομένων (σύνολα python θα πνιγούν όμως για unhashable τύπους δεδομένων). Παρ 'όλα αυτά, παρακάτω είναι μερικά πιο φλύαρη και άσχημο C / Java-όπως ορισμοί:

  1. τοπολογική ισοδυναμία:

    t1==t2 που σημαίνει (t1.left==t2.left and t1.right==t2.right) or (t1.left==t2.right and t1.right==t2.left)

  2. ταξινομημένα ισοδυναμίας δέντρο:

    t1==t2 που σημαίνει (t1.left==t2.left and t1.right==t2.right)

Οι ορισμοί παραπάνω είναι αναδρομικές? Δηλαδή, θα αναλάβει η ισότητα έχει οριστεί για τις υποδένδρων και βάσης περιπτώσεις ήδη, η οποία έχει.


υποσημείωση:

quote: tree1-> παιδί == tree2-> παιδιού

Αυτό δεν είναι μια έγκυρη δήλωση, διότι ένας κόμβος δέντρο δεν έχει ένα μόνο παιδί.

Απαντήθηκε 12/10/2011 στις 02:20
πηγή χρήστη

ψήφοι
7

Δεν νομίζω ότι αυτό είναι μια παράλογη ερώτηση. Μια απλή επαναλαμβανόμενη λύση είναι

boolean equals(x, y)
{
  if (x == null)
  {
    return y == null;
  }
  if (y == null)
  {
    return false;
  }
  if (x.val != y.val)
  {
    return false;
  }
  if (equals(x.left, y.left) && equals(x.right, y.right))
  {
    return true;
  }
  if (equals(x.left, y.right) && equals(x.right, y.left))
  {
    return true;
  }
  return false;
}

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

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

Αυτή η έννοια της http://en.wikipedia.org/wiki/Canonicalization που ακολουθείται από τους απλούς ισότητας επιλύει επίσης ερωτήματα σχετικά με το εάν πραγματικά έχετε μια σχέση ισοδυναμίας. Μια σχέση ισοδυναμίας είναι ισοδύναμη με ένα διαμέρισμα. Τακτική ισότητα είναι προφανώς ένα διαμέρισμα. Αν συγκρίνετε x και y συγκρίνοντας f (x) και f (y) που ακολουθείται από μια σχέση ισοδυναμίας έχετε μια κατάτμηση των Χ και Υ, και ως εκ τούτου μια σχέση ισοδυναμίας.

Σκέφτεστε περισσότερα γι 'αυτό, νομίζω ότι ο τρόπος για να κάνουν είτε canonicalisation ή την ισότητα, τη δοκιμή εύλογα αποδοτικό είναι να εργαστεί από κάτω προς τα πάνω, το σχολιασμό κάθε κόμβο με μια συμβολική η αξία των οποίων αντανακλά το αποτέλεσμα των συγκρίσεων με άλλους κόμβους, έτσι ώστε να μπορείτε να συγκρίνετε κόμβους και τα κάτω τους υποδένδρων, απλά να συγκρίνει τις μάρκες.

Έτσι το πρώτο βήμα για την ισότητα είναι π.χ. χρησιμοποιήστε ένα πίνακα κατακερματισμού για να σχολιάσετε κάθε φύλλο με τις μάρκες που είναι ίσες μόνο όταν οι τιμές στα φύλλα είναι ίσες. Στη συνέχεια, για τους κόμβους των οποίων μόνο τα παιδιά είναι τα φύλλα, χρησιμοποιούν π.χ. έναν πίνακα κατακερματισμού να αναθέσει περαιτέρω τις μάρκες, έτσι ώστε οι μάρκες σε αυτές τις κόμβους είναι ίσες μόνο όταν τα φύλλα, αν υπάρχουν, κάτω από εκείνα κόμβους αγώνα. Στη συνέχεια, μπορείτε να πάτε ένα ακόμη βήμα μπροστά, και αυτή τη φορά μπορείτε να συγκρίνετε μάρκες σε παιδί κόμβοι, αντί να την αναδρομική κάτω από το δέντρο εκεί. Το κόστος της ανάθεσης μάρκες με αυτόν τον τρόπο πρέπει να είναι γραμμικό ως προς το μέγεθος των δέντρων που εμπλέκονται. Στην κορυφή μπορείτε να συγκρίνετε τα δέντρα απλά συγκρίνοντας τις μάρκες στη ρίζα.

Απαντήθηκε 12/10/2011 στις 06:57
πηγή χρήστη

ψήφοι
0

Διάβασα τις ερωτήσεις όπως: δίνονται δύο δυαδικά δέντρα, για κάθε βάθος στο δέντρο, να μάθετε αν σύνολο των παιδιών τους καλύπτονται σε κάθε άλλο.

Αυτό μπορεί να κωδικοποιηθεί σχετικά εύκολη.

Απαντήθηκε 12/10/2011 στις 12:30
πηγή χρήστη

ψήφοι
0

Λύση χωρίς αναδρομή στην Ruby

def same? top_t1, top_t2
  for_chek << [top_t1, top_t2]   # (1) put task for check into queue

  while t1,t2 = for_check.shift  # (2)
    return false unless t1.children.count == t2.children.count  # generally for non-binary tree, but also needed for controlling of nil children
    break if t1.children.empty?

    t1_children = t1.children.sort # this is sorted arrays
    t2_children = t2.children.sort # of childrens      
    return false unless t1_children == t2_children  # (3)

    0.upto(t1_children.count - 1) do |i|
      for_check << [t1_children[i], t2_children[i]]  # put equivalent child pairs into queue
    end
  end
  return true
end

Ruby συμβουλές σύνταξη:

  • (1) τοποθέτηση στοιχείου σε συστοιχία: arr << elem? σε αυτή την περίπτωση for_checkείναι συστοιχία συστοιχίες
  • (2) παράλληλη ανάθεση: t1,t2 = [item1, item2]. Το ίδιο μεarr = [item1, item2]; t1 = arr[0]; t2 = arr[1]
  • (3) t1_children == t2_childrenυποτίθεται αντίστοιχη συμπεριφορά του == για αυτό το είδος των αντικειμένων. Πιο λεπτομερή θα είναι t1_children.map { |el| el.val } == t2_children.map { |el| el.val }- εδώ mapπαράγει σειρά από Vals.
Απαντήθηκε 15/10/2011 στις 16:17
πηγή χρήστη

ψήφοι
1

Συγκρίνετε τα δέντρα που χρησιμοποιούν την προσέγγιση αγιοποίηση προτείνεται από @mcdowella . Η διαφορά είναι ότι η προσέγγισή μου δεν απαιτεί O(N)πρόσθετο αριθμό wrt μνήμη των κόμβων στο δέντρο:

# in Python
from collections import namedtuple
from itertools import chain

# Tree is either None or a tuple of its value and left, right trees
Tree = namedtuple('Tree', 'value left right')

def canonorder(a, b):
    """Sort nodes a, b by their values.

    `None` goes to the left
    """
    if (a and b and a.value > b.value) or b is None:
        a, b = b, a # swap
    return a, b

def canonwalk(tree, canonorder=canonorder):
    """Yield all tree nodes in a canonical order.

    Bottom-up, smaller children first, None is the smallest
    """
    if tree is not None:
        children = tree[1:]
        if all(t is None for t in children): return # cut None leaves
        children = canonorder(*children)            
        for child in chain(*map(canonwalk, children)):
            yield child
    yield tree 

canonwalk()απαιτεί O(N*M)βήματα και O(log(N)*M)μνήμη για να αποδώσει όλους τους κόμβους σε ένα δέντρο, όπου Nείναι ο συνολικός αριθμός των κόμβων, Mαριθμό των παιδιών κάθε κόμβος έχει (είναι 2 για δυαδικά δένδρα).

canonorder()θα μπορούσε εύκολα να γενικευθεί για οποιαδήποτε εκπροσώπηση κόμβο και κάθε αριθμό των παιδιών. canonwalk()απαιτεί μόνο ότι ένα δέντρο μπορεί να έχει πρόσβαση άμεσα τα παιδιά του ως ακολουθία.

Η λειτουργία σύγκρισης που καλεί canonwalk():

from itertools import imap, izip_longest

unset = object() 
def cmptree(*trees):
    unequal = False # allow root nodes to be unequal
    # traverse in parallel all trees under comparison
    for nodes in izip_longest(*imap(canonwalk, trees), fillvalue=unset):
        if unequal:
            return False # children nodes are not equal
        if any(t is unset for t in nodes):
            return False # different number of nodes
        if all(t is not None for t in nodes):
            unequal = any(nodes[-1].value != t.value for t in nodes)
        else: # some are None
            unequal = any(t is not None for t in nodes)
    return True # equal

Παράδειγμα

    5         6
   / \       / \           they are equal.
  1   2     2   1
 /     \   /    / 
3       4 4     3

tree1 = Tree(5, 
             Tree(1, 
                  Tree(3, None,None), None), 
             Tree(2, 
                  None, Tree(4, None, None)))
tree2 = Tree(6, 
             Tree(2, Tree(4, None, None), None),
             Tree(1, Tree(3, None, None), None))
print cmptree(tree1, tree2)

Παραγωγή

True
Απαντήθηκε 15/10/2011 στις 21:10
πηγή χρήστη

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