Hvordan konvertere et binært tre til binært søketre på stedet, dvs. vi kan ikke bruke noen ekstra plass

stemmer
12

Hvordan konvertere et binært tre til binært søketre på stedet, det vil si, vi kan ikke bruke noen ekstra plass.

Publisert på 05/04/2010 klokken 05:46
kilden bruker
På andre språk...                            


10 svar

stemmer
0

En binærtreet vanligvis er et binært søketre, i så fall ingen konvertering er nødvendig.

Kanskje du trenger å avklare strukturen av hva du konverterer fra. Er din kilde treet ubalansert? Er det ikke bestilt av nøkkelen du vil søke på? Hvordan fikk du kommer til kilden treet?

Svarte 05/04/2010 kl. 06:00
kilden bruker

stemmer
0

Vel, hvis dette er et intervju spørsmålet, det første jeg ville blurt ut (med null selve tanken) er dette: gjenta hele binære rekursivt og og finne det minste elementet. Ta den ut av binære treet. Nå gjenta prosessen der du gjenta hele treet og finne det minste elementet, og legge den som en forelder av den siste element som finnes (med foregående element bli den nye nodens venstre barn). Gjenta så mange ganger som nødvendig inntil den opprinnelige treet er tom. På slutten, er du igjen med den verst tenke sorterte binærtreet - en lenket liste. Pekeren peker til rotnoden, som er den største element.

Dette er en fryktelig algoritme all-around - O (n ^ 2) gangtid med den verst tenkebinærtreet utgang, men det er en anstendig utgangspunkt før du kommer opp med noe bedre, og har fordelen av at du er i stand til å skrive koden for den i ca 20 linjer på en tavle.

Svarte 05/04/2010 kl. 06:50
kilden bruker

stemmer
10

Du gir ikke mye å gå på, men hvis kravet er hva jeg tror det er, har du et binært tre som allerede er opprettet og sitter i minnet, men ikke sortert (slik du vil at det skal sorteres, uansett).

Jeg antar at de tre noder ligne

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

Jeg er også forutsatt at du kan lese C

Mens vi kunne bare sitte rundt lurer på hvorfor dette treet noensinne ble laget uten å ha blitt opprettet i sortert rekkefølge som ikke gjør oss noe godt, så jeg skal ignorere det og bare takle sortere det.

Kravet om at ingen ekstra plass brukes er merkelig. Midlertidig vil det være ekstra plass, hvis bare på stakken. Jeg kommer til å anta at det betyr at du ringer malloc eller noe sånt, og også at den resulterende treet har å bruke mer minne enn den opprinnelige usortert treet.

Den første og enkleste løsning er å gjøre en preorder traversering av den usorterte treet fjernes hver node fra det treet og gjør en sortert innsetting i et nytt tre. Dette er O (n + n log (n)), som er O (n log (n)).

Hvis dette ikke er hva de ønsker, og du er nødt til å bruke rotasjoner og ting ..... det er fryktelig!

Jeg tenkte at du kunne gjøre dette ved å gjøre en merkelig versjon av en haug slag, men jeg fikk problemer. En annen ting som kom til tankene, noe som ville være forferdelig sakte, ville gjøre en merkelig versjon av boblesortering på treet.

For dette hver node blir sammenlignet og eventuelt byttet med hver av det direkte barn (og dermed også med sin overordnede) gjentatte ganger til du traversere treet og ikke finne noen nødvendige bytteavtaler. Gjør en shaker sort (boblesortering som går fra venstre til høyre og høyre til venstre) versjon av dette ville fungere best, og etter den første pass ville du ikke trenger å krysse ned undertrær som ikke ser ut av drift i forhold til det overordnede .

Jeg er sikker på at enten dette algorthm var tenkt opp av noen andre før meg, og har et kult navn som jeg ikke vet, eller at det er fundamentalt feil på noen måte at jeg ikke ser.

Kommer opp med run-time beregninger for andre forslag er en ganske komplisert. Først trodde jeg at det ville bare være O (n ^ 2), som boble og shaker slags, men jeg kan ikke tilfredsstille meg selv som undertreet traversering unngåelse ikke kan vinne nok til å gjøre det litt bedre enn O (n ^ 2). I hovedsak boble og shaker slags få dette optimalisering også, men bare i endene hvor total sortedness oppstår tidlig, og du kan hogge ned grensene. Med dette treet versjonen får du oppurtunities å muligens unngå biter i midten av settet også. Vel, som jeg sa, det er nok skjebnesvangert feil.

Svarte 05/04/2010 kl. 07:09
kilden bruker

stemmer
-1

Gjør inorder traversering av det binære treet og lagre resultatet. sortere resultatet i acending orden danne binært søketre ved å ta midt element av den sorterte listen som root (dette kan gjøres ved hjelp av binære søk). så vi får balansert binært søketre.

Svarte 15/12/2010 kl. 04:12
kilden bruker

stemmer
1

Har følgende algoritme for å nå løsningen.

1) finne den for etterfølgeren uten å bruke noe plass.

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) Gjør for traversering uten å bruke plass.

a) Finn den første noden inorder traversering. Det bør forlot de fleste barn av treet hvis den har, eller venstre side av første til høyre barn hvis den har, eller høyre barnet selv. b) Bruk ovenfor algoritme for å finne ut inoder etterfølger av første noden. c) Gjenta trinn 2 for alle de returnerte etterfølger.

Bruk over to algoritme og gjøre for overgang på binærtreet uten å bruke ekstra plass. Danner det binære søketre når du gjør traversering. Men kompleksiteten er O(N2)worst case.

Svarte 15/12/2010 kl. 04:35
kilden bruker

stemmer
-1

heap slags treet .. nlogn kompleksitet ..

Svarte 13/06/2011 kl. 19:23
kilden bruker

stemmer
2

Gjør Postorder overgang og fra det skape et binært søketre.

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';
    }
}
Svarte 10/01/2012 kl. 04:27
kilden bruker

stemmer
14

Konvertere Binary Tre til en dobbeltlenket liste-kan gjøres inplace i O (n)
Deretter sortere det ved hjelp av flettesortering, nlogn
konvertere listen tilbake til et tre - O (n)

Enkelt nlogn løsning.

Svarte 29/08/2012 kl. 14:37
kilden bruker

stemmer
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;
}
Svarte 23/12/2012 kl. 23:49
kilden bruker

stemmer
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);
}
Svarte 14/09/2013 kl. 06:56
kilden bruker

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