Hogyan lehet átalakítani a bináris fa bináris keresési fa in-place, azaz nem tudjuk használni az extra helyet.
Hogyan lehet átalakítani a bináris fa bináris keresési fa in-place, azaz nem tudjuk használni az extra helyet
A bináris fa általában van egy bináris keresési fa, ebben az esetben nincs szükség konverzióra.
Lehet, hogy tisztázni kell a szerkezet, amit konvertálás. A forrás fa kiegyensúlyozatlan? Vajon nem rendeli el a kulcsot a keresni kívánt on? Hogyan érkezik meg a forrást fát?
Nos, ha ez egy interjú kérdés, az első dolog, amit kikotyog (nulla tényleges gondolat) ez: léptetjük a teljes bináris rekurzív és és megtalálni azt a legkisebb elemet. Vedd ki a bináris fa. Most ismételjük meg a folyamatot, ahol végighaladni az egész fát, és megtalálja azt a legkisebb elemet, és adja meg a szülő az utolsó elem talált (az előző elem lesz az új csomópont bal gyerek). Ismételje meg, ahányszor csak szükséges, amíg az eredeti fa üres. A végén, akkor marad a lehető legrosszabb kiválogatott bináris fa - egy láncolt lista. A mutató mutat a gyökér csomópont, amely a legnagyobb elem.
Ez egy szörnyű algoritmus minden-körül - O (n ^ 2) futási idő a lehető legrosszabb bináris fa kimenet, de ez egy tisztességes kiindulási pont, mielőtt jön valami jobb és megvan az az előnye akkor képes írni a kódot hogy körülbelül 20 sor egy táblára.
Nem ad sokat menni, de ha az a követelmény, amit úgy gondolom, hogy van egy bináris fa már létrehozott és ül memóriát, de nem rendezve (a kívánt módon, hogy ki kell válogatni, egyébként).
Én feltételezve, hogy a fa csomópontok kinéznie
struct tree_node {
struct tree_node * left;
struct tree_node * right;
data_t data;
};
Én is feltételezve, hogy el tudja olvasni a C
Bár tudnánk ülni kíváncsi, hogy miért ez a fa volt, amit valaha készítettek anélkül hozták létre, rendezetten, hogy nem csinál nekünk jó, úgyhogy figyelmen kívül hagyja, és csak foglalkozni válogatás.
Az a követelmény, hogy nem extra helyet kell használni páratlan. Átmenetileg nem lesz extra helyet, ha csak a verem. Megyek feltételezni, hogy ez azt jelenti, hogy a hívó malloc vagy valami ilyesmi, és azt is, hogy az így kapott fa használata nem több memóriát igényel, mint az eredeti osztályozatlan fa.
Az első és legegyszerűbb megoldás az, hogy nem lesz előrendelés bejárás A szétválogatás nélkül fa eltávolításával minden csomópont azt a fát, és ezzel egy rendezett behelyezés egy új fát. Ez O (n + n log (n)), ami O (n log (n)).
Ha ez nem az, amit akarnak, és fogsz kell használni forgatások és a cucc ..... ez szörnyű!
Azt hittem, hogy ezt megteheti ezzel páratlan változata egy halom fajta, de belefutottam problémák. A másik dolog, hogy nem jön szóba, ami rettenetesen lassú, akkor kell csinálni egy furcsa változatát buborék rendezés a fán.
Ehhez minden egyes csomópont képest, és esetleg cserélték mindegyik ez direkt gyerekeknek (és ennélfogva az anyavállalata) többször áthalad a fát, és nem találja el a szükséges swap. Ennek egy shaker sort (buborék sort, hogy megy balról jobbra és jobbról balra) változata ez működni fog a legjobban, és miután az első menetben, akkor nem kell, hogy áthalad le részfák hogy egyáltalán nem néz ki a rend szerint ez a szülő .
Biztos vagyok benne, hogy vagy ez algorthm gondolták fel valaki előttem, és van egy jó név, hogy én csak nem tudom, vagy azt, hogy alapvetően hibás valamilyen módon, hogy nem látok.
Jön a futtatási idő számítást a második javaslat egy elég bonyolult. Eleinte azt hittem, hogy ez csak O (n ^ 2), mint a buborék, és shaker fajta, de nem tudom kielégíteni magam, hogy a részfa bejárása elkerülésére esetleg nem nyer elég ahhoz, hogy egy kicsit jobb, mint O (n ^ 2). Lényegében buborék és shaker féle kap ez optimalizálás is, de csak a végein, ahol a teljes rendezettség korán jelentkezik és akkor vágja le a korlátokat. Ezzel a fa változat kapsz oppurtunities lehetőség szerinti elkerülése darabokat közepén a készlet is. Nos, mint mondtam, ez valószínűleg végzetesen hibás.
Tegye inorder bejárása a bináris fa és tárolja az eredményt. A legújabb eredmény acending érdekében létrehozzák a bináris keresési fa figyelembe középső eleme a rendezett listát root (ez lehet tenni bináris kereséssel). így jutunk kiegyensúlyozott bináris keresési fa.
Ne következő algoritmust, hogy elérjük a megoldást.
1) megtalálják a annak érdekében, hogy utódja használata nélkül helyet.
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) Van, hogy bejárás nélkül helyet.
a) Határozza meg az első csomópont a inorder bejárása. Meg kell balra legtöbb gyermek a fát, ha van, vagy a bal első jobb gyerek, ha van, vagy a jobb gyermek is. b) használja a fenti algoritmust kideríteni inoder utódja első csomópontot. c) Ismételje meg a 2. lépést minden visszatért utódja.
Használd a fenti 2. algoritmus, és nem a bejárás érdekében a bináris fa használata nélkül extra helyet. Forma bináris keresési fa, amikor egy bejárás. De a bonyolultság O(N2)legrosszabb esetben.
kupac sort a fa .. nlogn bonyolultsága ..
Ne a postorder Bejárás és hogy hozzon létre egy bináris keresési fa.
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';
}
}
Átalakítás bináris fa egy kétszeresen kötött lista- lehet tenni a helyben végzett O (n)
Ezután rendezze meg az egyesítés sort, nlogn
átalakítani a listán hátát egy fának - O (n)
Egyszerű nlogn megoldás.
#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;
}
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);
}













