Come convertire un albero binario di albero binario di ricerca sul posto, vale a dire, non possiamo usare qualsiasi spazio extra

voti
12

Come convertire un albero binario di albero binario di ricerca sul posto, vale a dire, non possiamo usare tutto lo spazio aggiuntivo.

È pubblicato 05/04/2010 alle 06:46
fonte dall'utente
In altre lingue...                            


10 risposte

voti
0

Un albero binario di solito è un albero binario di ricerca, nel qual caso non è necessaria alcuna conversione.

Forse avete bisogno di chiarire la struttura di quello che si esegue la conversione. È il vostro albero dei sorgenti non bilanciata? Non è forse ordinato dal tasto che si desidera cercare? Come sei arrivato a l'albero dei sorgenti?

Risposto il 05/04/2010 a 07:00
fonte dall'utente

voti
0

Beh, se questo è un questione intervista, la prima cosa che vorrei spifferare (da zero pensiero reale) è questo: iterare l'intero binario in modo ricorsivo e e trovare l'elemento più piccolo. Tirarla fuori della albero binario. Ora, ripetere il processo in cui si itera l'intero albero e trovare il più piccolo elemento e aggiungerlo come un genitore dell'ultimo elemento trovato (con l'elemento precedente diventare figlio sinistro del nuovo nodo). Ripetere tante volte quanto necessario fino a quando l'albero originale è vuota. Alla fine, si sono lasciati con la peggiore possibile albero binario ordinata - una lista collegata. Il puntatore punta al nodo radice, che è l'elemento più grande.

Si tratta di un orribile algoritmo di all-around - O (n ^ 2) tempo di esecuzione con la peggiore possibile uscita albero binario, ma è un punto di partenza decente prima di venire con qualcosa di meglio e ha il vantaggio di voi di essere in grado di scrivere il codice per in circa 20 linee su una lavagna.

Risposto il 05/04/2010 a 07:50
fonte dall'utente

voti
10

Non dare molto per andare avanti, ma se il requisito è quello che penso che sia, si dispone di un albero binario già creato e seduta in memoria, ma non allineati (il modo in cui si desidera essere ordinato, in ogni caso).

Sto assumendo che i nodi della struttura sembrano

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

Sono anche supponendo che si può leggere C

Mentre potremmo semplicemente sedersi intorno chiedendosi perché questo albero è stato mai creato senza essere stato creato in modo ordinato che non ci serve a niente, quindi mi ignorarlo e basta trattare con smistamento.

Il requisito che essere utilizzato nessun spazio aggiuntivo è dispari. Temporaneamente non ci sarà spazio extra, anche se solo in pila. Ho intenzione di assumere che significa che chiamando malloc o qualcosa del genere e, inoltre, che l'albero risultante è di utilizzare non più memoria rispetto l'albero non ordinato originale.

Il primo e più semplice soluzione è quella di fare un attraversamento preordine dell'albero indifferenziati rimuovendo ogni nodo da quell'albero e facendo un inserimento ordinato in un nuovo albero. Questo è O (n + n log (n)), che è O (n log (n)).

Se questo non è ciò che vogliono e si sta andando ad avere per usare rotazioni e roba ..... questo è orribile!

Ho pensato che si potrebbe fare questo facendo una versione dispari di un mucchio sorta, ma mi sono imbattuto in problemi. Un'altra cosa che è venuto in mente, che sarebbe terribilmente lento, potrebbe fare una versione dispari di bubble sort sull'albero.

Per questo ogni nodo viene confrontata e possibilmente scambiato con ciascuno di esso per bambini diretti (e quindi anche con il suo genitore) fino a quando si attraversa l'albero e non si trova alcuna swap necessari. Facendo uno shaker sort (bubble sort che va da sinistra a destra e la destra a sinistra) di questo avrebbe funzionato meglio, e dopo il passo iniziale, non avrebbe bisogno di attraversare le sottostrutture che non si affacciano su ordine rispetto al suo genitore .

Sono sicuro che sia questo algorthm è stato pensato da qualcun altro prima di me e ha un nome fresco che io proprio non lo so, o che è fondamentalmente errata, in qualche modo che non sto vedendo.

Venendo con i calcoli di runtime per il secondo suggerimento è un piuttosto complicato. In un primo momento ho pensato che sarebbe semplicemente O (n ^ 2), come bolla e shaker sorta, ma non posso soddisfare me stesso che scanso sottostruttura attraversamento potrebbe non vincere abbastanza per renderlo un po 'meglio di O (n ^ 2). Essenzialmente bolla e shaker sorta ottenere questa ottimizzazione troppo, ma solo alle estremità dove sortedness totale si verifica precocemente e si può abbattere i limiti. Con questa versione albero si ottiene molta opportunità di evitare possibilmente pezzi nel mezzo del set pure. Beh, come ho detto, probabilmente è fatalmente incrinata.

Risposto il 05/04/2010 a 08:09
fonte dall'utente

voti
-1

Fare ordine simmetrico dell'albero binario e memorizzare il risultato. ordinare il risultato per formare l'albero binario di ricerca prendendo elemento centrale della lista ordinata come root acending (questo può fare usando la ricerca binaria). in modo da ottenere equilibrato albero binario di ricerca.

Risposto il 15/12/2010 a 05:12
fonte dall'utente

voti
1

Non seguente algoritmo per raggiungere la soluzione.

1) trovare il successore al fine senza l'utilizzo di qualsiasi spazio.

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) fare ordine di attraversamento senza utilizzare spazio.

a) Trovare il primo nodo di ordine simmetrico. Dovrebbe lasciato la maggior parte del bambino dell'albero se ha, o di sinistra del primo figlio a destra se ha, o se stesso figlio destro. b) Utilizzare algoritmo di cui sopra per scoprire inoder successore del primo nodo. c) Ripetere il passaggio 2 per tutti il ​​successore restituito.

Utilizzare sopra 2 algoritmo e fare l'in ordine di attraversamento su albero binario senza l'utilizzo di spazio in più. Formare l'albero binario di ricerca quando si fa l'attraversamento. Ma la complessità è O(N2)peggiore dei casi.

Risposto il 15/12/2010 a 05:35
fonte dall'utente

voti
-1

mucchio sorta l'albero .. complessità nlogn ..

Risposto il 13/06/2011 a 20:23
fonte dall'utente

voti
2

Fare la postorder Traversal e da quella di creare un albero binario di ricerca.

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';
    }
}
Risposto il 10/01/2012 a 05:27
fonte dall'utente

voti
14

Convertire albero binario a una lista- doppiamente legato può essere fatto inplace in O (n)
quindi ordinare utilizzando merge sort, nlogn
convertire l'elenco di nuovo ad un albero - O (n)

soluzione nlogn semplice.

Risposto il 29/08/2012 a 15:37
fonte dall'utente

voti
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;
}
Risposto il 24/12/2012 a 00:49
fonte dall'utente

voti
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);
}
Risposto il 14/09/2013 a 07:56
fonte dall'utente

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