Jak převést binární strom binárního vyhledávacího stromu na místě, tedy nemůžeme použít žádný další prostor

hlasů
12

Jak převést binární strom binárního vyhledávacího stromu v místě, tedy nemůžeme použít žádný další prostor.

Položena 05/04/2010 v 06:46
zdroj uživatelem
V jiných jazycích...                            


10 odpovědí

hlasů
0

Binární strom obvykle je binární vyhledávací strom, přičemž v tomto případě není nutná žádná konverze.

Možná, že je třeba vyjasnit strukturu, co se konverze z. Je váš zdroj strom nevyvážený? Je to nenařídil klíčem, který chcete hledat v? Jak jste se dostali na zdrojovém stromu?

Odpovězeno 05/04/2010 v 07:00
zdroj uživatelem

hlasů
0

No, pokud se jedná o rozhovor otázku, první věc, kterou bych vybreptnout (s nulovým skutečné myšlení), je toto: opakovat celý binární rekurzivně a a najít nejmenší prvek. Vezměte ho do binárního stromu. Nyní, opakujte postup, kde iteraci celý strom a najít nejmenší prvek, a přidejte ji jako rodič posledního elementu nalezeného (s předchozím prvkem stává levé dítě nového uzlu). podle potřeby, dokud původní strom je prázdný opakovat tolikrát, kolikrát. Na konci, jste odešel s nejhorším možným tříděného binárního stromu - propojeného seznamu. Ukazatel ukazuje na kořenový uzel, který je největší prvek.

To je hrozný algoritmus all-around - O (n ^ 2), doba provozu s nejhorším možným binárního stromu výstupu, ale je to slušné východisko, než přijít s něčím lepším a má tu výhodu, že budete schopni psát kód je asi 20 řádků na tabuli.

Odpovězeno 05/04/2010 v 07:50
zdroj uživatelem

hlasů
10

Nemusíte dát mnohem dál, ale v případě, že požadavek je to, co myslím, že je máte binární strom již vytvořili a sedí v paměti, ale není seřazena (tak, jak chcete, aby se třídit, tak jako tak).

Jsem za předpokladu, že uzly strom vypadat

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

Jsem také za předpokladu, že si můžete přečíst C

I když jsme mohli jen sedět a přemýšlel, proč byl tento strom byl kdy vytvořen, aniž by byla vytvořena v seřazeném pořadí, který nedělá nám k ničemu, takže budu to ignorovat a jen se zabývají jejich třídění.

Požadavek, aby byla použita žádná zvláštní prostor je lichý. Dočasně bude prostor navíc, i kdyby jen na stacku. Budu předpokládat, že to znamená, že volání malloc nebo něco podobného, ​​a také to, že výsledný strom se musí používat více paměti než původní netříděného stromu.

První a nejjednodušší řešení je provést předobjednávku průchod netříděného stromu odstraňování každý uzel z toho stromu a dělá seřazené vložení do nového stromu. To je O (n + n log (n)), který je O (n log (n)).

Pokud to není to, co chtějí, a budete muset použít rotace a tak ..... to je hrůza!

Myslel jsem si, že byste mohli udělat tím, že dělá podivnou verzi haldy druhu, ale já běžel do problémů. Další věc, která se přijde na mysl, což by bylo strašně pomalý, bude dělat podivnou verzi bubble druhu na stromě.

Za tímto účelem každý uzel je ve srovnání a případně vyměnil s každým z jeho přímé děti (a tudíž i se svým rodičem) opakovaně, dokud procházet strom a nenacházíte potřebné swapy. Dělá vibrační druh (bubble sort, že jde zleva doprava a zprava doleva) verze této opravy bude fungovat nejlépe, a po počátečním průchodu nebudete muset procházet dolů podstromy, že nevypadal mimo pořadí s ohledem na to rodič ,

Jsem si jistý, že buď to algortimus vymyslel někdo jiný přede mnou a má cool jméno, které já prostě nevím, nebo že je zásadně chybné nějakým způsobem, že nevidím.

Přijít s run-time výpočty pro druhý návrh je docela složité. Zprvu jsem si myslel, že by to prostě bylo O (n ^ 2), stejně jako bublina a shaker druhů, ale nemohu uspokojit sebe, že vyhýbání podstrom průchod nemusí vyhrát natolik, aby to trochu lepší než O (n ^ 2). V podstatě bublina a vibrační druhy získat tuto optimalizaci taky, ale jen na koncích, kde celková sortedness vyskytuje brzy a můžete pokácet limity. S tímto stromem verzi dostanete oppurtunities aby případně nedošlo k kusy ve středu sady stejně. No, jak jsem řekl, je to zřejmě fatálně chybné.

Odpovězeno 05/04/2010 v 08:09
zdroj uživatelem

hlasů
-1

Dělat nezbytného průchod binárního stromu a uložení výsledku. seřadit výsledek acending objednávkový formulář binární vyhledávací strom, vypočítává střední prvek z tříděného seznamu jako root (totéž lze provést pomocí binárního vyhledávání). tak dostaneme vyvážený strom binárního vyhledávání.

Odpovězeno 15/12/2010 v 05:12
zdroj uživatelem

hlasů
1

Ještě následující algoritmus k dosažení řešení.

1) najít v pořadí nástupce bez použití jakéhokoli prostoru.

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) udělat, aby průchod bez použití prostoru.

a) Najděte prvního uzlu nezbytného průchod. Mělo by opustil většinu dítě stromu, pokud to má, nebo vlevo od prvního pravého potomka, pokud má nebo vpravo dítě samo. b) Použití výše algoritmus pro zjištění inoder nástupce prvního uzlu. c) Opakujte krok 2 pro všechny vrácené nástupce.

Používat více než 2 algoritmus a proveďte v pořadí průchod na binárního stromu bez použití více prostoru. Vytvoří binární vyhledávací strom, když dělal traversal. Ale složitost je O(N2)nejhorší případ.

Odpovězeno 15/12/2010 v 05:35
zdroj uživatelem

hlasů
-1

heap sort stromu .. nlogn složitost ..

Odpovězeno 13/06/2011 v 20:23
zdroj uživatelem

hlasů
2

Proveďte postorder Traversal a od toho vytvoří binární vyhledávací strom.

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';
    }
}
Odpovězeno 10/01/2012 v 05:27
zdroj uživatelem

hlasů
14

Převést binární strom do dvojnásob propojeny Seznam Titulů lze provést inplace v O (n),
pak třídit je pomocí merge sort, nlogn
převést seznamu zpět do stromu - O (n)

Jednoduché nlogn řešení.

Odpovězeno 29/08/2012 v 15:37
zdroj uživatelem

hlasů
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;
}
Odpovězeno 24/12/2012 v 00:49
zdroj uživatelem

hlasů
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);
}
Odpovězeno 14/09/2013 v 07:56
zdroj uživatelem

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