Για να βρείτε τα μεγαλύτερα στοιχείο μικρότερο από K σε ένα BST

ψήφοι
17

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

Στο παρακάτω δέντρο,

for K = 13, result = 12
for K = 10, result = 8
for K = 1 (or) 2, result = -1

      10

  5       12

2   8   11  14

Δοκίμασα την παρακάτω λογική. Αλλά είναι καθόλου καλύτερα τρόπος για να γίνει αυτό;

int findNum(node* node, int K)
{
        if(node == NULL)
        {
                return -1;
        }
        else if(K <= node->data)
        {
                return findNum(node->left,K);
        }
        else if(K > node->data)
        {
                int t = findNum(node->right,K);
                return t > node->data ? t : node->data;
        }

        return -1;
}
Δημοσιεύθηκε 13/06/2011 στις 19:22
πηγή χρήστη
Σε άλλες γλώσσες...                            


5 απαντήσεις

ψήφοι
1

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

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

Απαντήθηκε 13/06/2011 στις 19:29
πηγή χρήστη

ψήφοι
3

Πιστεύω στην χρήση τυποποιημένων εγκαταστάσεων της βιβλιοθήκης. Έτσι, η λύση μου χρησιμοποιεί std::set. :-)

int largest_num_smaller_than(std::set<int> const& set, int num)
{
    std::set<int>::const_iterator lb(set.lower_bound(num));
    return lb == set.begin() ? -1 : *--lb;
}
Απαντήθηκε 13/06/2011 στις 19:33
πηγή χρήστη

ψήφοι
19

Αυτό είναι O (log n), το οποίο είναι το ελάχιστο. Ωστόσο, μπορείτε να βελτιώσετε την απόδοση (η οποία φαίνεται να είναι το κύριο πράγμα αυτές οι ερευνητές ενδιαφέρονται για) και να εξαλείψει την πιθανότητα υπερχείλισης στοίβας (Τάντα!) Με την εξάλειψη της αναδρομής ουράς, μετατρέποντας αυτό σε έναν βρόχο. Επίσης, ο κωδικός σας δεν λειτουργεί αν το δέντρο περιέχει τους αρνητικούς αριθμούς ... αν σημαίνει μη-αρνητικών ακεραίων, θα πρέπει να το πω έτσι, αλλά αν ο ερευνητής μόλις είπε «ακέραιοι» τότε θα πρέπει ελαφρώς διαφορετικό κώδικα και μια διαφορετική API. (Θα μπορούσε να κρατήσει την ίδια λειτουργία με την υπογραφή, αλλά επιστρέφουν Κ αντί -1 στην αποτυχία.)

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

Εδώ είναι μια εφαρμογή:

// Return the greatest int < K in tree, or K if none.
int findNum (Node* tree, int K)
{
    int val = K;

    while( tree )
        if( tree->data >= K )
            tree = tree->left;
        else{
            val = tree->data; 
            tree = tree->right;
        }

    return val;
}
Απαντήθηκε 13/06/2011 στις 20:25
πηγή χρήστη

ψήφοι
5

Νομίζω ότι η ιδέα εδώ είναι να καταγράψει το τελευταίο κόμβο μετά την οποία θα κινηθεί προς τα δεξιά υποδένδρο. Ως εκ τούτου, ο κωδικός θα πρέπει να (έχει ενημερωθεί)

int findNum (Node *node, int K)
{
    Node* last_right_move = NULL;

    while (node)
    {
        if (K<=node->data)
            node = node->left;
        else
        {
            last_right_move = node;
            node = node->right;
        }
    }

    if (last_right_move)
        return last_right_move->data;
    else
        return NOT_FOUND;  // defined previously. (-1 may conflict with negative number)
}
Απαντήθηκε 14/06/2011 στις 03:06
πηγή χρήστη

ψήφοι
1

Ποια η πρώτη απάντηση είπε, και εδώ είναι η λογική πίσω από τους οποίους δεν μπορεί να πάρει καλύτερα από O (log n). Ψάχνετε για το μεγαλύτερο αριθμό λιγότερο από Κ Αυτό είναι αρκετά κοντά στην κλήση BST-αναζήτησης / πάρετε.

Αν και πρωτότυπο αλγόριθμο σας φαίνεται αρκετά καλό, νομίζω ότι αυτό θα είναι ταχύτερη:

    int findNum (node root, int K) {
        if(root == null) return -1;

        if(K > root.val) { 
           if(root.right != null) return findNum(root.right, K);               
           else return root.val; 
        }

        return findNum(root.left, K); //look in left subtree

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

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