Stackoverflow durum BST geçme

oy
4

Benim atama biri için bir bağlantı tabanlı BST C (ikili arama ağacı) ++ uygulamasını söyleyin. Ben bütün sınıf yazdım ve her şey iyi çalışır, ancak benim atama için çalışma sürelerini çizmek için beni sorar:

a.  A sorted list of 50000, 75000, and 100000 items
b.  A random list of 50000, 75000, and 100000 items

Bu iyi, ben numaraları ekleyebilirsiniz ama aynı zamanda aramamı ister FindHeight()ve CountLeaves()ağaç üzerinde yöntemleri. Benim sorunum kullanarak iki işlevi uyguladık olmasıdır recursion. Ben alıyorum alıyorum numaralarının bu kadar büyük bir liste var yana stackoverflowistisna.

İşte benim sınıf tanımı var:

template <class TItem>
class BinarySearchTree
{
public:
    struct BinarySearchTreeNode
    {
    public:
        TItem Data;
        BinarySearchTreeNode* LeftChild;
        BinarySearchTreeNode* RightChild;
    };

    BinarySearchTreeNode* RootNode;

    BinarySearchTree();
    ~BinarySearchTree();

    void InsertItem(TItem);

    void PrintTree();
    void PrintTree(BinarySearchTreeNode*);

    void DeleteTree();
    void DeleteTree(BinarySearchTreeNode*&);

    int CountLeaves();
    int CountLeaves(BinarySearchTreeNode*);

    int FindHeight();
    int FindHeight(BinarySearchTreeNode*);

    int SingleParents();
    int SingleParents(BinarySearchTreeNode*);

    TItem FindMin();
    TItem FindMin(BinarySearchTreeNode*);

    TItem FindMax();
    TItem FindMax(BinarySearchTreeNode*);
};

FindHeight () Uygulama

template <class TItem>
int BinarySearchTree<TItem>::FindHeight()
{
    return FindHeight(RootNode);
}

template <class TItem>
int BinarySearchTree<TItem>::FindHeight(BinarySearchTreeNode* Node)
{
    if(Node == NULL)
        return 0;

    return 1 + max(FindHeight(Node->LeftChild), FindHeight(Node->RightChild));
}

CountLeaves () uygulaması

template <class TItem>
int BinarySearchTree<TItem>::CountLeaves()
{
    return CountLeaves(RootNode);
}

template <class TItem>
int BinarySearchTree<TItem>::CountLeaves(BinarySearchTreeNode* Node)
{
    if(Node == NULL)
        return 0;
    else if(Node->LeftChild == NULL && Node->RightChild == NULL)
        return 1;
    else
        return CountLeaves(Node->LeftChild) + CountLeaves(Node->RightChild);
}

Ben özyineleme olmadan iki yöntem uygulayabilirsiniz nasıl düşünmeye çalıştım ama tamamen stumped. Herkes herhangi bir fikir var mı?

Oluştur 10/11/2011 saat 00:52
kaynak kullanıcı
Diğer dillerde...                            


5 cevaplar

oy
1

STL altında yatan RB-ağacı kullanır gibi özyineleme olmadan yaprakları saymak için, bir yineleyici kavramını kullanmak std::setve std::mapbir Oluştur ... begin()ve end()bu durumda sol içinde (sipariş ilk ve son düğümü indentifies size ağaç fonksiyonu -En düğüm ve en sağ düğüm). Sonra adlı bir fonksiyon oluşturuyorum

BinarySearchTreeNode* increment(const BinarySearchTreeNode* current_node)

göz önüne alındığında, bir için current_node, ağaçtaki bir sonraki düğüme bir işaretçi döndürür. Işe bu uygulama için unutmayın, ekstra gerekecektir parentsizin de işaretçi nodeyineleme işlemine yardımcı olmak üzere tip.

Sizin algoritması increment()aşağıdaki gibi görünecektir:

  1. Geçerli düğümün sağ çocuğu olup olmadığını kontrol edin.
  2. sağ çocuk varsa, bu doğru altağacın en soldaki düğümü bulmak için bir süre-döngü kullanın. Bu "sonraki" düğüm olacaktır. Aksi takdirde 3. adıma gidin.
  3. Geçerli düğüm üzerinde hiçbir sağ çocuk varsa, o zaman geçerli düğüm kendi üst düğümün sol-çocuk olup olmadığını görmek için kontrol edin.
  4. adım 3. doğruysa aksi sonraki adımı gitmek, bu noktada durabilir, böylece daha sonra "sonraki" düğüm, üst düğümdür.
  5. adım 3. yanlış ise, o anki düğüm ebeveynin sağ çocuğudur. Böylece sen onun üst düğümün sol çocuğu bir düğüm rastlamak kadar while döngüsü kullanılmasının bir sonraki ana düğüme kadar hareketli tutmak gerekir. Bu sol alt düğümünün ebeveyn sonra "sonraki" düğüm olacak ve siz durdurabilirsiniz.
  6. Son olarak, kök adım 5. döner sizi, ardından geçerli düğüm ağacında son düğümdür ve yineleyici ağacının dolup dolmadığını.

Nihayet bir gerekir bool leaf(const BinarySearchTreeNode* current_node)belirli bir düğüm yaprak olup olmadığını test edecek işlevi. Böylece size karşı fonksiyonu sadece bir kez bitti nihai sayımını dönen, ağacın olsa yineleme ve tüm yaprak düğümleri bulabilirsiniz.

Eğer özyineleme olmadan dengesiz bir ağacın maksimum derinliği ölçmek istiyorsanız, siz, ağacın içinde olacak insert()işlevi, bir düğüm takıldığı derinlikte takip etmek gerekir. Bu sadece bir değişken olabilir nodedüğüm ağacında takıldığında ayarlanır tip. Daha sonra üç yinelemenize ve yaprak-düğümün maksimum derinliği bulabilirsiniz.

BTW, bu yöntemin karmaşıklığı maalesef hiçbir yerde O (log N) kadar güzel yakın ... O (K) olacak.

Cevap 10/11/2011 saat 01:01
kaynak kullanıcı

oy
3

O dengeli ise 100.000 düğümlerle bir ağaç üzerinde Özyinelemeye bir problem olmamalı. Derinliğinin sadece gösterilen uygulamalarda çok yığın kullanmak değildir, belki 17 olacaktır. (log2(100,000) = 16.61). Bu yüzden belki ağaç kuruyor kodu doğru dengeleme değil gibi görünüyor.

Cevap 10/11/2011 saat 01:02
kaynak kullanıcı

oy
1

olabilir Eğer insert yaparken bu hesaplamak gerekir. yani düğüm nesnesindeki yüksekliği gibi bir tam sayı alanı eklemek, düğüm yükseklikleri saklayın. Ayrıca ağaç için sayaçlar yükseklik ve yaprakları vardır. Bir düğüm eklediğinizde, üst ise, bir yaprak, yaprak sayısı doesnt değişikliği (idi), ancak Ayrıca yeni düğümün yüksekliği ebeveynin yüksekliği + 1, yani büyüktür dolayısıyla eğer, 1 ile yaprak sayısını artırmak ağacın şimdiki yüksekliğinden daha sonra güncelleyin. Onun bir ödev, bu yüzden gerçek kodla ilgili yardım alışkanlık

Cevap 10/11/2011 saat 01:05
kaynak kullanıcı

oy
2

Bulduğum bu sayfayı bu tekrarlanmasını kullanır birine yineleme kullandığında bir işlev dönüştürme mekaniği bahsediyor çünkü çok aydınlatıcı.

Bu da kodunu gösteren örnekler vardır.

Cevap 10/11/2011 saat 01:06
kaynak kullanıcı

oy
1

Ara sıra ağaç dengeleyin. Senin ağacı) FindHeight (üzerinde stackoverflow gelmiyorsa, bu senin ağaç demektir yolu dengesiz. Ağaç dengeli ise sadece 100000 elemanları için yaklaşık 20 düğümlerin derinliğinde olmalıdır.

Yeniden dengeleme dengesiz ikili ağacın en kolay (ama oldukça yavaş) yolu, bir dizi tahsis etmektir TItem, ağaçtaki tüm verileri tutacak kadar büyük sıralanmış sırayla içine tüm verilerinizi eklemek ve silmek tüm düğümlerin . Sonra yinelemeli diziden ağacı yeniden. Kök ortada düğümdür. root->leftSol yarısının ortası olan root->rightsağ yarısında ortasıdır. Yinelemeli tekrarlayın. Bu yeniden dengelemek için en kolay yolu, ancak slowish ve geçici belleğe birçok alır. Eğer ağaç olduğunu tespit Öte yandan, sadece bunu yapmak zorunda çok dengesiz, (uç üzerindeki derinlik fazla 100 olan).

diğer (daha iyi) seçeneği ekler sırasında dengesini sağlamaktır. Bunu yapmanın en kolay yolu, geçerli düğümün altında kaç düğümleri takip etmektir. Sağ alt sol çocuk olarak iki kat daha fazla "çocuk" düğümler daha varsa, sol "döndürmek". Ve tersi de geçerlidir. Ağaç internet üzerinden tüm döner nasıl yapılacağına ilişkin instrcutions var. Bu biraz daha yavaş ekler yapar, ama o zaman ilk seçenek oluşturur renkliydi masif tezgahlarda yok. Öte yandan, size önemsiz olmadığı, döner gibi sürekli "çocuklar" sayar tüm güncellemeniz gerekir.

Cevap 10/11/2011 saat 01:08
kaynak kullanıcı

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