İkili arama ağacı tabanlı Dengeleme Dize (İmla kontrolü için)

oy
1

Güncelleme: Ben üye işlevlerini isBalanced (), isRightHeavy (), isLeftHeavy tanımak doAVLBalance gelmediğinden dolayı, çalışmaya Dengeleme alınamıyor. Ve nedenini bilmiyorum! Yavaşlama uyumsuz ve bunu düzeltmeye olamazdı ... o yüzden yolumu yapıyor çalıştı ... ve o üye işlevleri yoktur söylüyor ben tam kuşak örneğini (3 yanıt) denedim ama olsun, ne zaman açıkça yapmak.

Hata: Sınıf 'IntBinaryTree:.. TreeNode isRightHeavy 'Geçen 4 saat :( denedikten sonra şaşırıp' hayır üyesi var' aşağıda Güncelleme kod, yardım çok takdir !!

Ben yaratıyorum İkili arama ağacı tabanlı Dize ve bir Dengeli ağaç yapmak gerekir. Bunu nasıl yaparım? * Yardım lütfen !! Şimdiden teşekkürler!

BinarySearchTree.cpp:

    bool IntBinaryTree::leftRotation(TreeNode *root)
    {
        //TreeNode *nodePtr = root;  // Can use nodePtr instead of root, better?
        // root, nodePtr, this->?

        if(NULL == root)
        {return NULL;}

        TreeNode *rightOfTheRoot = root->right;
        root->right = rightOfTheRoot->left;
        rightOfTheRoot->left = root;

        return rightOfTheRoot;
    }

    bool IntBinaryTree::rightRotation(TreeNode *root)
    {
        if(NULL == root)
        {return NULL;}
        TreeNode *leftOfTheRoot = root->left;
        root->left = leftOfTheRoot->right;
        leftOfTheRoot->right = root;

        return leftOfTheRoot;
    }

    bool IntBinaryTree::doAVLBalance(TreeNode *root)
    {


        if(NULL==root)
            {return NULL;}
        else if(root->isBalanced()) // Don't have isBalanced
            {return root;}

        root->left = doAVLBalance(root->left);
        root->right = doAVLBalance(root->right);

        getDepth(root); //Don't have this function yet

        if(root->isRightHeavy()) // Don't have isRightHeavey
        {
            if(root->right->isLeftheavey())
            {
                root->right = rightRotation(root->right);
            }
            root = leftRotation(root);
        }
        else if(root->isLeftheavey()) // Don't have isLeftHeavey
        {
            if(root->left->isRightHeavey())
            {
                root->left = leftRotation(root->left);
            }
            root = rightRotation(root);
        }
        return root;
    }

    void IntBinaryTree::insert(TreeNode *&nodePtr, TreeNode *&newNode)
    {
        if(nodePtr == NULL)
            nodePtr = newNode;                  //Insert node
        else if(newNode->value < nodePtr->value)
            insert(nodePtr->left, newNode);     //Search left branch
        else
            insert(nodePtr->right, newNode);    //search right branch
    }

//
// Displays the number of nodes in the Tree


int IntBinaryTree::numberNodes(TreeNode *root)
{
    TreeNode *nodePtr = root;

    if(root == NULL)
        return 0;

    int count = 1; // our actual node
    if(nodePtr->left !=NULL)
    { count += numberNodes(nodePtr->left);
    }
    if(nodePtr->right != NULL)
    {
        count += numberNodes(nodePtr->right);
    }
    return count;
} 

    // Insert member function

    void IntBinaryTree::insertNode(string num)
    {
        TreeNode *newNode; // Poitner to a new node.

        // Create a new node and store num in it.
        newNode = new TreeNode;
        newNode->value = num;
        newNode->left = newNode->right = NULL;

        //Insert the node.
        insert(root, newNode);
    }

    // More member functions, etc.

BinarySearchTree.h:

class IntBinaryTree
{
private:
    struct TreeNode
    {
        string value; // Value in the node
        TreeNode *left; // Pointer to left child node
        TreeNode *right; // Pointer to right child node
    };

    //Private Members Functions
    // Removed for shortness
    void displayInOrder(TreeNode *) const;


public:
    TreeNode *root;
    //Constructor
    IntBinaryTree()
        { root = NULL; }
    //Destructor
    ~IntBinaryTree()
        { destroySubTree(root); }

    // Binary tree Operations
    void insertNode(string);
    // Removed for shortness

    int numberNodes(TreeNode *root);
    //int balancedTree(string, int, int); // TreeBalanced

    bool leftRotation(TreeNode *root);
    bool rightRotation(TreeNode *root);
    bool doAVLBalance(TreeNode *root); // void doAVLBalance();
    bool isAVLBalanced();

    int calculateAndGetAVLBalanceFactor(TreeNode *root);

    int getAVLBalanceFactor()
    {
        TreeNode *nodePtr = root; // Okay to do this? instead of just
        // left->mDepth
        // right->mDepth

        int leftTreeDepth = (left !=NULL) ? nodePtr->left->Depth : -1;
        int rightTreeDepth = (right != NULL) ? nodePtr->right->Depth : -1;
        return(leftTreeDepth - rightTreeDepth);
    }

    bool isRightheavey() { return (getAVLBalanceFactor() <= -2); }

    bool isLeftheavey() { return (getAVLBalanceFactor() >= 2); }


    bool isBalanced()
    {
        int balanceFactor = getAVLBalanceFactor();
        return (balanceFactor >= -1 && balanceFactor <= 1);
    }


    int getDepth(TreeNode *root); // getDepth

    void displayInOrder() const
        { displayInOrder(root); }
    // Removed for shortness
};
Oluştur 02/08/2011 saat 05:00
kaynak kullanıcı
Diğer dillerde...                            


3 cevaplar

oy
1

Bunu yapmanın birçok yolu vardır, ama aslında bütün olarak bunu öneririm. Dizgilerde bir BST saklamak istiyorsanız, çok daha iyi seçenek vardır:

  1. önceden yazılmış bir ikili arama ağacı sınıfını kullanın. C ++ std :: set sınıf dengeli bir ikili arama ağacı gibi aynı zaman garanti vermez ve genellikle gibi uygulanmaktadır. Bu BST sahibi haddeleme daha kullanmak ölçüde daha kolaydır.

  2. Bunun yerine bir traydan kullanın. tray veri yapısı, basit ve dizeleri bir BST daha etkilidir hiç dengelenmesini gerektiren ve BST daha hızlıdır.

Eğer gerçekten kendi dengeli BST yazmak gerekiyorsa, birçok seçenek var. dengelemesini kullanacak Çoğu BST uygulamaları son derece karmaşıktır ve kalbin zayıf değildir. Bir treap doğrusu uygulamak çok kolay iki dengeli BST yapılardır bir yayvan ağacı, ya uygulanmasına öneririm. Onlar yukarıda olmasına kod daha hem daha karmaşık ve ben de bu kısa uzayda bir uygulama sağlayamaz, ancak bu yapılar için bir Wikipedia arama size nasıl devam tavsiye bol vermelidir.

Bu yardımcı olur umarım!

Cevap 02/08/2011 saat 06:21
kaynak kullanıcı

oy
1

Ne yazık ki, biz programcılar edebi hayvanlardır.

bir "Dengeli" ağaç olun.

Bağımlı bağlamı "Dengeli" dir. Giriş veri yapıları sınıflar genelde büyük derinlik düğüm ve en az derinlik düğüm arasındaki fark minimum olduğu "dengeli" olarak bir ağaç bakın. Sir Templatetypedef tarafından belirtildiği gibi Ancak, bir yayvan ağaç dengeleyici bir ağaç olarak kabul edilir. Birkaç düğümleri sık bir anda birlikte erişilen o durumlarda oldukça iyi ağaçları dengeleyebilirsiniz olmasıdır. O geleneksel ikili ağacın daha yayvan ağacındaki verilere ulaşmak için daha az düğüm traversals almasıdır bu durumlarda . Öte yandan, bir erişim bazında erişim bazda en kötü durum performansı bağlantılı liste kadar kötü olabilir.

Bağlı liste açılmışken ...

Çünkü aksi olmadan Okuduğum bir bağlantılı liste ile aynı olduğunu ve amacı yendi "Dengeleme".

Bu olabilir kadar kötü olabilir ama randomize uçlar için öyle değil. Zaten-sıralandığını eklerseniz, en ikili arama ağacı uygulamaları bir şişirilmiş gibi verileri depolayacak ve listeyi bağlantılı emretti. Sürekli ağacın bir tarafını yapıyolar sadece Ancak, bu. (. Bir ikili ağaca vb 1, 2, 3, 4, 5, 6, 7, ... takmadan düşünün kağıt üzerinde deneyin ve neler olacağını görün.)

Eğer teorik kötü durum-garantili olmalıdır anlamda denge varsa, ben kırmızı-siyah ağaçlara bakmanızı öneririz. (Google, ikinci bağlantı oldukça iyidir.)

dengeleme herhangi bir ekstra kod olmadan olasılıksal olacağını şekilde - bu özel senaryo için makul bir şekilde onu dengelemek için varsa, ben tamsayı endeksleri ve iyi bir hash fonksiyonu ile gitmek istiyorum. Yani, demek Karşılaştırma fonksiyonu karma gibi görünmesi için ise (strA) <yerine artık bende olanı karma (STRB). (Bu durum için hızlı ama etkili karma için FNV karma bakmak. Google'daki birinci hit. Faydalı kodu görene kadar aşağı gidin.) Eğer isterseniz uygulama verimliliği ayrıntıları endişelenebilirsin. (Örneğin, hem sen hiç değişmez diziden biri beri karşılaştırmak her zaman sağlamalarının gerçekleştirmek gerekmez.)

Ondan ile alabilirsiniz Eğer süre bir krizi konum ve hızlı bir şey istiyorsanız, şiddetle ikincisi önerilir. Kendi yükseklik dengeli ikili ağaç rulo gerektiğinde pratikte son derece yararlı olduğun Aksi takdirde, kırmızı-siyah ağaçlar değerli.

Son olarak, yukarıdaki kodunuzu adresleme, aşağıdaki kodu yorumları görmek:

int IntBinaryTree::numberNodes(TreeNode *root)
{
    if(root = NULL) // You're using '=' where you want '==' -- common mistake.
                    // Consider getting used to putting the value first -- that is,
                    // "NULL == root". That way if you make that mistake again, the
                    // compiler will error in many cases.
        return 0;
    /*
    if(TreeNode.left=null && TreeNode.right==null)  // Meant to use '==' again.
    { return 1; }

    return numberNodes(node.left) + numberNodes(node.right);
    */

    int count = 1; // our actual node
    if (left != NULL)
    {
        // You likely meant 'root.left' on the next line, not 'TreeNode.left'.
        count += numberNodes(TreeNode.left);
        // That's probably the line that's giving you the error.
    }
    if (right != NULL)
    {
        count += numberNodes(root.right);
    }
    return count;
}
Cevap 02/08/2011 saat 08:10
kaynak kullanıcı

oy
1

Programcılar ikili ağaçları dengelemek için AVL ağacı kavramlarını kullanırlar. Oldukça basit. Daha fazla bilgi online olarak bulunabilir. Hızlı wiki linki

Aşağıda AVL algoritmasını kullanarak ağaç dengesini yapar örnek kod verilmiştir.

Node *BinarySearchTree::leftRotation(Node *root)
{
    if(NULL == root)
    {
        return NULL;
    }
    Node *rightOfTheRoot = root->mRight;
    root->mRight = rightOfTheRoot->mLeft;
    rightOfTheRoot->mLeft = root;

    return rightOfTheRoot;
}

Node *BinarySearchTree::rightRotation(Node *root)
{
    if(NULL == root)
    {
        return NULL;
    }
    Node *leftOfTheRoot = root->mLeft;
    root->mLeft = leftOfTheRoot->mRight;
    leftOfTheRoot->mRight = root;

    return leftOfTheRoot;
}

Node *BinarySearchTree::doAVLBalance(Node *root)
{
    if(NULL == root)
    {
        return NULL;
    }
    else if(root->isBalanced())
    {
        return root;
    }

    root->mLeft  = doAVLBalance(root->mLeft);
    root->mRight = doAVLBalance(root->mRight);

    getDepth(root);

    if(root->isRightHeavy())
    {
        if(root->mRight->isLeftHeavy())
        {
            root->mRight = rightRotation(root->mRight);
        }
        root = leftRotation(root);
    }
    else if(root->isLeftHeavy())
    {
        if(root->mLeft->isRightHeavy())
        {
            root->mLeft = leftRotation(root->mLeft);
        }
        root = rightRotation(root);
    }

    return root;
}

Sınıf Tanımı

class BinarySearchTree
{
public:
    // .. lots of methods 
    Node *getRoot();
    int getDepth(Node *root);

    bool isAVLBalanced();
    int calculateAndGetAVLBalanceFactor(Node *root);
    void doAVLBalance();

private:
     Node *mRoot;
};

class Node
{
public:
    int  mData;
    Node *mLeft;
    Node *mRight;
    bool mHasVisited;
    int mDepth;
public:

    Node(int data)
    : mData(data),
      mLeft(NULL),
      mRight(NULL),
      mHasVisited(false),
      mDepth(0)
    {
    }

    int getData()              { return mData; }

    void setData(int data)     { mData = data;  }

    void setRight(Node *right) { mRight = right;}

    void setLeft(Node *left)   { mLeft = left; }

    Node * getRight()          { return mRight; }

    Node * getLeft()           { return mLeft; }

    bool hasLeft()             { return (mLeft != NULL);  }

    bool hasRight()            { return (mRight != NULL); }

    bool isVisited()           { return (mHasVisited == true); }

    int getAVLBalanceFactor()
    {
        int leftTreeDepth = (mLeft != NULL) ? mLeft->mDepth : -1;
        int rightTreeDepth = (mRight != NULL) ? mRight->mDepth : -1;
        return(leftTreeDepth - rightTreeDepth);
    }

    bool isRightHeavy() { return (getAVLBalanceFactor() <= -2); }

    bool isLeftHeavy()  { return (getAVLBalanceFactor() >= 2);  }

    bool isBalanced()
    {
        int balanceFactor = getAVLBalanceFactor();
        return (balanceFactor >= -1 && balanceFactor <= 1);
    }
};
Cevap 02/08/2011 saat 17:45
kaynak kullanıcı

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