ikili arama ağacına bir ikili ağaç nasıl dönüştürülür yerinde, yani, herhangi bir ekstra alan kullanamazsınız

oy
12

Yerinde ikili arama ağacına, yani bir ikili ağacı nasıl dönüştürülür, herhangi ekstra alan kullanamaz.

Oluştur 05/04/2010 saat 06:46
kaynak kullanıcı
Diğer dillerde...                            


10 cevaplar

oy
0

Bir ikili ağaç genellikle olduğu hiçbir dönüşüm gereklidir, bu durumda bir ikili arama ağacı,.

Belki sen dönüştürme şeyin yapısını açıklamak gerekir. Kaynak ağacı dengesiz mi? Eğer üzerinde aramak istediğiniz anahtarı tarafından sipariş değil mi? Nasıl kaynak ağacının ulaştılar?

Cevap 05/04/2010 saat 07:00
kaynak kullanıcı

oy
0

ve tekrar eden tüm ikili yineleme ve küçük elemanı bulmak: Bu bir görüşme soru buysa, ilk şey şudur (sıfır fiili düşünceyle) yumurtlamak ederim. İkili ağaçtan götürün. Şimdi, tüm ağacı yineleme ve en küçük elemanı bulmak işlemi tekrarlayın ve (yeni düğümün sol çocuğu olma önceki eleman ile) bulunan son elemanın bir ebeveyn olarak ekleyin. Orijinal ağaç boşalana kadar gerektiği kadar kez tekrarlayın. Bağlantılı bir listede - sonunda, olası en kötü sıralı ikili ağacın kalır. İşaretçiniz büyük unsurdur kök düğümü, işaret ediyor.

Bu korkunç bir algoritma çepeçevre - O (n ^ 2) olası en kötü ikili ağaç çıkışı ile çalışma süresi, ama daha iyi bir şeyle gelmeden önce iyi bir başlangıç ​​noktası olduğunu ve sizin için kod yazmak mümkün olma avantajına sahiptir bir beyaz tahta yaklaşık 20 hatlarında bu.

Cevap 05/04/2010 saat 07:50
kaynak kullanıcı

oy
10

Sen elimizde pek vermeyin, ama gereklilik ben öyle düşündüğüm şey ise, bir ikili ağaç zaten oluşturulmuş ve bellekte oturan fakat (bunu zaten sıralanabilir istediğiniz şekilde) sıralanır var.

Ağaç düğümleri gibi bakmak varsayarak yaşıyorum

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

Ben de C okuyabilir varsayarak yaşıyorum

Biz sadece bu ağaç hiç bize bir faydası yapmaz sıralı düzende oluşturulmuş edilmeksizin oluşturulma nedeni merak oturup, bu yüzden olabilir iken bunu göz ardı edip sadece sıralama ile uğraşmak gerekir.

hiçbir ekstra boşluk kullanılmalıdır gereksinimi garip. Geçici olarak yalnızca yığın, fazladan boşluk olacak. Onun gibi malloc falan çağırmadan anlamına geldiğini varsaymak gidiyorum ve elde edilen ağaç sınıflandırılmamış orijinal ağacın daha fazla bellek kullanmak zorunda da söyledi.

İlk ve en kolay çözüm o ağaçtan her düğümü kaldırıp yeni ağaca sıralanmış bir ekleme yapıyor sıralanmamış ağacının bir ön sipariş geçişini yapmaktır. Bu yağ (n + n (n O olduğu log (n)), log (n)).

Bu istedikleri ve rotasyonlar ve malzeme kullanmak zorunda gidiyoruz gibi değilse ..... o korkunç!

Sana bir yığın sıralama garip bir versiyonunu yaparak bu yapabileceğini düşünmüştüm ama sorunlarla karşılaştı. korkunç yavaş olacağını akla geldi başka bir şey, ağaç üzerinde kabarcık tür garip bir versiyonunu yapmak istiyorum.

Bu her düğüm karşılaştırıldı ve muhtemelen onunla her biriyle takas edilir için, ağaç travers ve gerekli takaslarını bulmuyorum kadar arka arkaya (dolayısıyla aynı zamanda ebeveyn ile ve) direkt çocukları var. (Sağ ve sola soldan sağa gider sıralama baloncuk) bu sürümü bir çalkalayıcı tür yapmak iyi çalışacak ve ilk geçişte sonra, yani ana göre bozuk bakmadı alt ağaçlar aşağı hareket etmesi gerekli olmaz .

Bu Algortimanın ya karşımda başkası tarafından düşünülmüş ve ben sadece bilmiyorum düzgün isim vardır ki eminim yoksa ben göremiyorum bir şekilde temelde kusurlu olduğunu.

İkinci öneri için çalışma zamanı hesaplamaları ile geliyor oldukça karmaşıktır. İlk başta ben ^ basitçe (n ^ 2), kabarcık ve çalkalayıcı türlü gibi ama alt ağaç geçişi kaçınma (n O olmadığı kadar biraz daha iyi yapmak için yeterli kazanmak değil diye kendimi tatmin edemez Ç olacağını düşündük 2). Esasen kabarcık ve çalkalayıcı sıralar ama sadece toplam sortedness erken meydana uçta da bu optimizasyona almak ve sınırlarını devirmek olabilir. Bu ağaç sürümü ile muhtemelen de setin ortasında parçalarını engellemek için Olanakları kalma olsun. Dediğim gibi, muhtemelen ölümcül kusurlu oluyor.

Cevap 05/04/2010 saat 08:09
kaynak kullanıcı

oy
-1

İkili ağacın kastetmek inorder yapın ve sonucu saklayın. emir root olarak sıralı listenin orta eleman alarak ikili arama ağacı oluşturmak acending sonucu (bu ikili arama kullanılarak yapılabilir edebilirsiniz) sıralamak. bu yüzden dengeli ikili arama ağacı olsun.

Cevap 15/12/2010 saat 05:12
kaynak kullanıcı

oy
1

algoritması aşağıdaki çözüme ulaşmak için vermeyin.

1) Herhangi bir boşluk kullanmadan sipariş halefi bulmak.

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) boşluk kullanmadan sipariş kastetmek yapın.

a) inorder kastetmek ilk düğümü bulun. O varsa ağacın en çocuğa sola veya ilk sağa çocuğun sol o varsa, ya da sağ çocuk kendisi olmalıdır. b) birinci düğümün halefi inoder bulma algoritması üzerinde kullanın. Tüm iade halefi c) 2. adımı tekrarlayın.

2 algoritma üzerinde kullanın ve ekstra alan kullanmadan ikili ağaç üzerinde sipariş kastetmek yapmak. Geçişi yaparken ikili arama ağacı oluşturun. Ama karmaşıklığı olduğunu O(N2)kötü durum.

Cevap 15/12/2010 saat 05:35
kaynak kullanıcı

oy
-1

sıralama ağaç .. nlogn karmaşıklığını yağdırmak ..

Cevap 13/06/2011 saat 20:23
kaynak kullanıcı

oy
2

Postorder Traversal'i yapın ve bundan bir ikili arama ağacı oluşturun.

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';
    }
}
Cevap 10/01/2012 saat 05:27
kaynak kullanıcı

oy
14

O (n) 'de INPLACE yapılabilir bir iki kat bağlantılı listesi-İkiliden Ağacı dönüştürme
Sonraki sıralama bu tür birleştirme nlogn kullanılarak
O (n) - Bir ağaca geri listeyi dönüştürme

Basit nlogn çözüm.

Cevap 29/08/2012 saat 15:37
kaynak kullanıcı

oy
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;
}
Cevap 24/12/2012 saat 00:49
kaynak kullanıcı

oy
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);
}
Cevap 14/09/2013 saat 07:56
kaynak kullanıcı

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