Πώς να μετατρέψετε ένα δυαδικό δέντρο σε δυαδικό δέντρο αναζήτησης επί τόπου, δηλαδή, δεν μπορούμε να χρησιμοποιήσουμε οποιαδήποτε επιπλέον χώρο

ψήφοι
12

Πώς να μετατρέψετε ένα δυαδικό δέντρο σε δυαδικό δέντρο αναζήτησης επί τόπου, δηλαδή, δεν μπορούμε να χρησιμοποιήσουμε οποιαδήποτε επιπλέον χώρο.

Δημοσιεύθηκε 05/04/2010 στις 06:46
πηγή χρήστη
Σε άλλες γλώσσες...                            


10 απαντήσεις

ψήφοι
0

Ένα δυαδικό δέντρο συνήθως είναι ένα δυαδικό δένδρο αναζήτησης, οπότε δεν απαιτείται μετατροπή.

Ίσως θα πρέπει να αποσαφηνιστεί η δομή του τι μετατροπή από. Είναι δέντρο πηγή σας ασύμμετρη; Είναι που δεν έχουν παραγγελθεί από το κλειδί που θέλετε να αναζητήσετε στο; Πώς θα φτάσετε στο δέντρο πηγαίου κώδικα;

Απαντήθηκε 05/04/2010 στις 07:00
πηγή χρήστη

ψήφοι
0

Λοιπόν, αν αυτό είναι μια ερώτηση συνέντευξης, το πρώτο πράγμα που θα ήθελα να βγάζω στη φόρα (με μηδενική πραγματική σκέψης) είναι το εξής: επαναλάβει ολόκληρη τη δυαδική αναδρομικά και και να βρούμε το μικρότερο στοιχείο. Πάρ 'το από το δυαδικό δέντρο. Τώρα, επαναλάβετε τη διαδικασία όπου θα επαναλάβει ολόκληρο το δέντρο και να βρει το μικρότερο στοιχείο, και να το προσθέσετε ως γονέας του τελευταίου στοιχείου που βρέθηκαν (με το προηγούμενο στοιχείο να γίνει αριστερό παιδί του νέου κόμβου). Επαναλάβετε όσες φορές χρειάζεται μέχρι το αρχικό δέντρο είναι άδειο. Στο τέλος, έχετε μείνει με το χειρότερο δυνατό ταξινομημένο δυαδικό δέντρο - μια συνδεδεμένη λίστα. δείκτης σας δείχνει στον κόμβο ρίζα, η οποία είναι το μεγαλύτερο στοιχείο.

Αυτό είναι ένα φρικτό αλγόριθμο all-around - O (n ^ 2) χρόνος τρέχει με τον χειρότερο δυνατό δυαδική έξοδος δέντρο, αλλά είναι ένα αξιοπρεπές σημείο εκκίνησης πριν καταλήξουμε σε κάτι καλύτερο και έχει το πλεονέκτημα ότι θα είναι σε θέση να γράψει τον κώδικα για το σε περίπου 20 γραμμές σε έναν πίνακα.

Απαντήθηκε 05/04/2010 στις 07:50
πηγή χρήστη

ψήφοι
10

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

Υποθέτω ότι οι κόμβοι δέντρο μοιάζουν

struct tree_node {
    struct tree_node * left;
    struct tree_node * right;
    data_t data;
};

Είμαι, επίσης, υποθέτοντας ότι μπορείτε να διαβάσετε C

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

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

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

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

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

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

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

Φθάνοντας με τους υπολογισμούς χρόνου εκτέλεσης για τη δεύτερη πρόταση είναι μια αρκετά περίπλοκη. Στην αρχή νόμιζα ότι θα ήταν απλά να είναι O (n ^ 2), όπως φούσκα και σέικερ είδη, αλλά δεν μπορώ να τον εαυτό μου πεποίθηση ότι η αποφυγή υποδένδρο διάσχιση δεν μπορεί να κερδίσει αρκετά για να κάνουν λίγο καλύτερα από O (n ^ 2). Ουσιαστικά φούσκα και σέικερ τα είδη πάρετε αυτό βελτιστοποίησης πάρα πολύ, αλλά μόνο στα άκρα, όπου η συνολική sortedness συμβαίνει νωρίς και μπορείτε να τεμαχίσει κάτω από τα όρια. Με αυτή την έκδοση το δέντρο θα έχετε oppurtunities να αποφευχθεί ενδεχομένως κομμάτια στη μέση του σετ, καθώς και. Λοιπόν, όπως είπα, είναι μάλλον θανάσιμα ελαττώματα.

Απαντήθηκε 05/04/2010 στις 08:09
πηγή χρήστη

ψήφοι
-1

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

Απαντήθηκε 15/12/2010 στις 05:12
πηγή χρήστη

ψήφοι
1

Να ακόλουθο αλγόριθμο για την επίτευξη της λύσης.

1) βρείτε το στο διάδοχο σειρά, χωρίς τη χρήση οποιουδήποτε χώρου.

Node InOrderSuccessor(Node node)
{ 
    if (node.right() != null) 
    { 
        node = node.right() 
        while (node.left() != null)  
            node = node.left() 
        return node 
    }
    else
    { 
        parent = node.getParent(); 
        while (parent != null && parent.right() == node)
       { 
            node = parent 
            parent = node.getParent() 
        } 
        return parent 
    } 
} 

2) Να με διάσχιση ώστε χωρίς τη χρήση του χώρου.

α) Βρείτε την πρώτη κόμβο της inorder διάσχισης. Θα πρέπει να αφεθεί πιο παιδί του δέντρου αν έχει, ή προς τα αριστερά της πρώτης δικαιώματος του παιδιού αν έχει, ή το δικαίωμα του παιδιού το ίδιο. β) Χρήση παραπάνω αλγόριθμο για να ανακαλύψει inoder διάδοχος του πρώτου κόμβου. γ) Επαναλάβετε το βήμα 2 για όλα τα επέστρεψε διάδοχο.

Χρησιμοποιήστε πάνω από 2 αλγόριθμο και να κάνει το σε διάσχιση ώστε σε δυαδικό δέντρο χωρίς τη χρήση επιπλέον χώρο. Διαμορφώστε το δυαδικό δέντρο αναζήτησης όταν κάνει διάσχισης. Αλλά η πολυπλοκότητα είναι O(N2)χειρότερη περίπτωση.

Απαντήθηκε 15/12/2010 στις 05:35
πηγή χρήστη

ψήφοι
-1

σωρό είδος του δέντρου .. nlogn πολυπλοκότητα ..

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

ψήφοι
2

Κάντε το PostOrder διάσχισης και από αυτό να δημιουργήσει ένα δυαδικό δέντρο αναζήτησης.

struct Node * newroot = '\0';

struct Node* PostOrder(Struct Node* root)
{
      if(root != '\0')
      {
          PostOrder(root->left);
          PostOrder(root->right);
          insertBST(root, &newroot);
      }
}

insertBST(struct Node* node, struct Node** root)
{
   struct Node * temp, *temp1;
   if( root == '\0')
   {
      *root == node;
       node->left ==  '\0';
       node->right == '\0';
   }
   else
   {
       temp = *root;
       while( temp != '\0')
       {
           temp1= temp;
           if( temp->data > node->data)
               temp = temp->left;
           else
               temp = temp->right;
       }
       if(temp1->data > node->data)
       {
           temp1->left = node;
       }
       else
       {
           temp1->right = node;
       }
       node->left = node->right = '\0';
    }
}
Απαντήθηκε 10/01/2012 στις 05:27
πηγή χρήστη

ψήφοι
14

Μετατροπή δυαδικού δένδρου σε διπλά συνδεδεμένη ΛΙΣΤΑ- μπορεί να γίνει επι τόπου σε O (n)
Στη συνέχεια, το είδος χρησιμοποιώντας ταξινόμηση με συγχώνευση, nlogn
Μετατρέψτε τον κατάλογο πίσω σε ένα δέντρο - O (n)

Απλή nlogn λύση.

Απαντήθηκε 29/08/2012 στις 15:37
πηγή χρήστη

ψήφοι
0
#include <stdio.h>
#include <stdlib.h>

typedef int data_t;

struct tree_node {
    struct tree_node * left;
    struct tree_node * right;
    data_t data;
};

        /* a bonsai-tree for testing */
struct tree_node nodes[10] =
{{ nodes+1, nodes+2, 1}
,{ nodes+3, nodes+4, 2}
,{ nodes+5, nodes+6, 3}
,{ nodes+7, nodes+8, 4}
,{ nodes+9, NULL, 5}
,{ NULL, NULL, 6}
,{ NULL, NULL, 7}
,{ NULL, NULL, 8}
,{ NULL, NULL, 9}
        };

struct tree_node * harvest(struct tree_node **hnd)
{
struct tree_node *ret;

while (ret = *hnd) {
        if (!ret->left && !ret->right) {
                *hnd = NULL;
                return ret;
                }
        if (!ret->left ) {
                *hnd = ret->right;
                ret->right = NULL;;
                return ret;
                }
        if (!ret->right) {
                *hnd = ret->left;
                ret->left = NULL;;
                return ret;
                }
        hnd = (rand() &1) ? &ret->left : &ret->right;
        }

return NULL;
}

void insert(struct tree_node **hnd, struct tree_node *this)
{
struct tree_node *ret;

while ((ret= *hnd)) {
        hnd = (this->data  < ret->data ) ? &ret->left : &ret->right;
        }
*hnd = this;
}

void show(struct tree_node *ptr, int indent)
{
if (!ptr) { printf("Null\n"); return; }

printf("Node(%d):\n", ptr->data);
printf("%*c=", indent, 'L');  show (ptr->left, indent+2);
printf("%*c=", indent, 'R');  show (ptr->right, indent+2);
}

int main(void)
{
struct tree_node *root, *this, *new=NULL;

for (root = &nodes[0]; this = harvest (&root);  ) {
        insert (&new, this);
        }

show (new, 0);
return 0;
}
Απαντήθηκε 24/12/2012 στις 00:49
πηγή χρήστη

ψήφοι
0
struct Node
{
    int value;
    Node* left;
    Node* right;
};

void swap(int& l, int& r)
{
    int t = l;
    l = r;
    r = t;
}

void ConvertToBST(Node* n, Node** max)
{
    if (!n) return;

    // leaf node
    if (!n->left && !n->right)
    {
        *max = n;
        return;
    }

    Node *lmax = NULL, *rmax = NULL;
    ConvertToBST(n->left, &lmax);
    ConvertToBST(n->right, &rmax);

    bool swapped = false;
    if (lmax && n->value < lmax->value)
    {
        swap(n->value, lmax->value);
        swapped = true;
    }

    if (rmax && n->value > rmax->value)
    {
        swap(n->value, n->right->value);
        swapped = true;
    }

    *max = n;
    if (rmax && rmax->value > n->value) *max = rmax;

    // If either the left subtree or the right subtree has changed, convert the tree to BST again
    if (swapped) ConvertToBST(n, max);
}
Απαντήθηκε 14/09/2013 στις 07:56
πηγή χρήστη

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